home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / misc / Fudgit233.lha / Source / src / command.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-16  |  76.6 KB  |  2,635 lines

  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <signal.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #ifndef NOSTDLIB_H
  7. #include <stdlib.h>
  8. #endif
  9. #ifndef NOUNISTD_H
  10. #include <unistd.h>
  11. #endif
  12.  
  13. #include "symbol.h"
  14. #include "code.h"
  15. #include "macro.h"
  16. #include "math.tab.h"
  17. #include "fudgit.h"
  18. #include "setshow.h"
  19. #include "help.h"
  20. #include "command.h"
  21. #include "readline/history.h"
  22. #include "head.h"
  23.  
  24. extern FILE *popen(const char *, const char *);
  25. extern int errno;
  26. extern int Ft_Interact;
  27. extern char *strstr(const char *, const char *);
  28. #ifndef AMIGA
  29. extern void exit(int);
  30. #endif
  31. extern int Ft_printversion(void);
  32. extern Ft_mathyyparse(void);
  33.  
  34. extern int hl_write_history(char *);
  35. extern int hl_append_history(int, char *);
  36. extern HIST_ENTRY **hl_history_list(void);
  37.  
  38. typedef union {
  39.     double db;
  40.     char* str;
  41.     } Vardesc;
  42.  
  43. static int Slowterm = 0;
  44. static int balmost(register char *str1, register char *str2);
  45. static int subcommand(int lvl, int argc, char **argv, char *l, Command *cmp);
  46. static int dataread(int argc, char **argv, int exec, Command *cmp);
  47. static int let(int argc, char **argv, char *line, Command *cmp);
  48. static int usage(Command *cmd);
  49. static int splitvar(int ifrom, int xto, char **argv, Vardesc *dbvec,
  50.     int *astringvec, Command *cmp);
  51. static int macrun(Macro *mac, int level);
  52. static void signal_off(void), signal_on(void);
  53.  
  54. /***********
  55. typedef int Do ();
  56. typedef struct {
  57.     char     *name;
  58.     Do       *func;
  59.     char     *fname;
  60.     char     *usage;
  61.     char     *help;
  62. } Command;
  63. ***********/
  64.  
  65. /* LEVEL 0 COMMANDS */
  66. int Ft_pmode(int c, char **v, char *l, Command *com);
  67. int Ft_help(int c, char **v, char *l, Command *com);
  68.  
  69. static int do_killplot(int c, char **v, char *l, Command *com);
  70. static int do_list(int c, char **v, char *l, Command *com);
  71. static int do_system(int argc, char **argv, char *line, Command *cmp);
  72. static int do_adjust(int argc, char **argv, char *l, Command *cmp);
  73. static int do_alias(int argc, char **argv, char *line, Command *cmp);
  74. static int go_append(int argc, char **argv, char *l, Command *cmp);
  75. static int do_cd(int argc, char **argv, char *l, Command *cmp);
  76. static int do_cmode(int argc, char **argv, char *l, Command *cmp);
  77. static int do_dumplot(int argc, char **argv, char *l, Command *cmp);
  78. static int do_echo(int argc, char **argv, char *line, Command *cmp);
  79. static int do_end(int c, char **v, char *l, Command *cmp);
  80. static int do_end(int c, char **v, char *l, Command *cmp);
  81. static int do_exec(int c, char **v, char *l, Command *cmp);
  82. static int do_quit(int c, char **v, char *l, Command *cmp);
  83. static int do_fft(int argc, char **argv, char *l, Command *cmp);
  84. static int do_fmode(int c, char **v, char *l, Command *cmp);
  85. static int do_foreach(int argc, char **argv, char *line, Command *cmp);
  86. static int do_free(int argc, char **argv, char *line, Command *cmp);
  87. static int do_let(int c, char **v, char *l, Command *cmp);
  88. static int do_lock(int argc, char **argv, char *l, Command *cmp);
  89. static int do_ls(int argc, char **argv, char *line, Command *cmp);
  90. static int do_pause(int argc, char **argv, char *line, Command *cmp);
  91. static int do_pwd(int argc, char **argv, char *l, Command *cmp);
  92. static int do_read(int c, char **v, char *l, Command *cmp);
  93. static int go_save(int argc, char **argv, char *l, Command *cmp);
  94. static int go_set(int argc, char **argv, char *l, Command *cmp);
  95. static int go_show(int argc, char **argv, char *l, Command *cmp);
  96. static int do_stop(int c, char **v, char *l, Command *cmp);
  97. static int do_unalias(int argc, char **argv, char *l, Command *cmp);
  98. static int do_unlock(int argc, char **argv, char *l, Command *cmp);
  99. static int do_vi(int c, char **v, char *line, Command *cmp);
  100. static int do_load(int argc, char **argv, char *l, Command *cmp);
  101. static int do_fit(int argc, char **argv, char *l, Command *cmp);
  102. #ifndef AMIGA
  103. static int do_hist(int argc, char **argv, char *mode, Command *cmp);
  104. #endif AMIGA
  105. static int do_invfft(int argc, char **argv, char *l, Command *cmp);
  106. static int do_parse(int argc, char **argv, char *line, Command *cmp);
  107. static int do_if(int argc, char **argv, char *line, Command *cmp);
  108. static int do_endif(int argc, char **argv, char *line, Command *cmp);
  109. static int do_else(int argc, char **argv, char *line, Command *cmp);
  110. static int do_while(int argc, char **argv, char *line, Command *cmp);
  111. static int do_udefmac(int argc, char **argv, char *l, Command *cmp);
  112. static int do_defmac(int argc, char **argv, char *l, Command *cmp);
  113. static int do_version(int argc, char **argv, char *l, Command *cmp);
  114. static int do_spline(int argc, char **argv, char *line, Command *cmp);
  115. static int do_smooth(int argc, char **argv, char *l, Command *cmp);
  116. static int do_install(int argc, char **argv, char *l, Command *cmp);
  117.  
  118. Command Ft_Cmds[] = {
  119.     {"?", do_list, "?", "",
  120.         "display this summary"},
  121.     {"ad!just", do_adjust, "adjust", "value_list",
  122.         "select parameter[s] to adjust in nonlinear fits"},
  123.     {"al!ias", do_alias, "alias", "command command_list",
  124.         "give another name to a command or a list of commands"},
  125.     {"ap!pend", go_append, "append", "object_type [object_list] filename",
  126.         "append different things to a given file"},
  127.     {"cd", do_cd, "cd", "directory",
  128.         "change current working directory"},
  129.     {"cm!ode", do_cmode, "cmode", "[cmode_commands]",
  130.         "switch to C mathematical mode"},
  131.     {"_d!umplot", do_dumplot, "_dumplot", "vector_list",
  132.         "dump given vector[s] to plotting program stdin"},
  133.     {"ec!ho", do_echo, "echo" ,"string",
  134.         "print a string to stdout"},
  135.     {"el!se", do_else, "else", "",
  136.         "fmode style else conditionnal statement"},
  137.     {"end", do_end, "end", "",
  138.         "terminate a do or foreach loop"},
  139.     {"en!dif", do_endif, "endif", "",
  140.         "terminate if conditionnal statement"},
  141.     {"exe!c", do_exec, "exec", "program vector_assignments",
  142.         "assign vector[s] to the output of a program"},
  143.     {"exi!t", do_quit, "exit", "",
  144.         "exit the program"},
  145.     {"fi!t", do_fit, "fit", "dep-VEC indep-VEC [sig-VEC]",
  146.         "fit given vector[s] using pre-selected method and function"},
  147.     {"ff!t", do_fft, "fft", "real-VEC ima-VEC tr-real-VEC tr-ima-VEC",
  148.         "Fourier transform the given vectors"},
  149.     {"fm!ode", do_fmode, "fmode", "",
  150.         "switch to fitting mode from either plotting or C mode"},
  151.     {"fore!ach", do_foreach, "foreach", "Var_Name `in' shell_command\n...\nend",
  152.         "make a macro loop over a series of values"},
  153.     {"fr!ee", do_free, "free", "varname|procname|funcname|\"@all\"...",
  154.         "remove the given object[s] from memory"},
  155.     {"he!lp", Ft_help, "help", "[command]",
  156.         "interactive help"},
  157. #ifndef AMIGA
  158.     {"hi!story", do_hist, "history", "",
  159.         "display complete history"},
  160. #endif
  161.     {"if", do_if, "if", "(condition) `then'",
  162.         "fmode if conditionnal statement"},
  163.     {"ins!tall", do_install, "install", "objfile objname[:|=]name(arg_list)...",
  164.         "link procedures(:) or functions(=) as name()"},
  165.     {"inv!fft", do_invfft, "invfft", "real-VEC ima-VEC tr-real-VEC tr-ima-VEC",
  166.         "Inverse Fourier transform the given vectors"},
  167.     {"_k!illplot", do_killplot, "_killplot", "",
  168.         "kill current plotting program"},
  169.     {"le!t", do_let, "let", "cmode_commands",
  170.         "give a command in C mode from the fitting mode"},
  171.     {"lo!ad", do_load, "load", "filename",
  172.         "read and interpret from command script file"},
  173.     {"loc!k", do_lock, "lock", "variable_list",
  174.         "turn variable[s] into constant[s]"},
  175.     {"ls", do_ls, "ls", "[files]",
  176.         "list files and directories"},
  177.     {"ma!cro", do_defmac, "macro", "name argno\n...\nstop",
  178.         "define a macro"},
  179.     {"parse", do_parse, "parse", "commands",
  180.         "test parsing"},
  181.     {"pa!use", do_pause, "pause", "delay [string]",
  182.         "suspend for the given delay and print string to stderr"},
  183.     {"pm!ode", Ft_pmode, "pmode", "[plotting_commands]",
  184.         "switch to plotting mode"},
  185.     {"pw!d", do_pwd, "pwd", "",
  186.         "print current working directory"},
  187.     {"q!uit", do_quit, "quit", "",
  188.         "same as exit"},
  189.     {"rea!d", do_read, "read", "file vector_assignments",
  190.         "assign vector[s] to column[s] of a file"},
  191.     {"rei!nstall", do_install, "reinstall",
  192.         "objfile objname[:|=]name(arg_list)...",
  193.         "relink procedures(:) or functions(=) as name()"},
  194.     {"sa!ve", go_save, "save", "objet_type [object_list] filename",
  195.         "save specified object[s] to a file"},
  196.     {"se!t", go_set, "set", "object value",
  197.         "set a lot of things"},
  198.     {"she!ll", do_system, "shell", "unix_commands",
  199.         "shell escape bang operator"},
  200.     {"sho!w", go_show, "show", "object_type [object_list]",
  201.         "show a lot of things"},
  202.     {"sm!ooth", do_smooth, "smooth", "sm-factor in-VEC out-VEC",
  203.         "smooth a vector by a given factor"},
  204.     {"sp!line", do_spline, "spline", "XVEC YVEC [dy1] [dyn]",
  205.         "initialize cubic spline interpolation"},
  206.     {"stop", do_stop, "stop", "",
  207.         "indicate end of macro"},
  208.     {"sy!stem", do_system, "system", "unix_commands",
  209.         "shell escape bang operator"},
  210.     {"una!lias", do_unalias, "unalias", "alias_list",
  211.         "undefine an alias"},
  212.     {"unm!acro", do_udefmac, "unmacro", "macro_list",
  213.         "undefine macro"},
  214.     {"unl!ock", do_unlock, "unlock", "constant_list",
  215.         "turn constant[s] into variable[s]"},
  216.     {"ve!rsion", do_version, "version", "",
  217.         "display version number"},
  218.     {"vi", do_vi, "vi", "file_list",
  219.         "call vi editor"},
  220.     {"wh!ile", do_while, "while", "(condition)\n...\nend",
  221.         "while conditionnal loop"},
  222.     {0,      0,        0,         0,       0}
  223.     };
  224.  
  225. /* FUNCTIONS */
  226. static int do_stfunc(int argc, char **argv, char *l, Command *cmp);
  227.  
  228. static Command Funcs[] = {
  229.     {"?", do_list, "set function ?", "",
  230.         "display this summary"},
  231.     {"c!osine", do_stfunc, "set function cosine", "",
  232.         "cosine series: n = 1,...N { A[n]*cos(n*X) }"},
  233.     {"e!xponential", do_stfunc, "set function exponential", "",
  234.         "exponential series: n = 2, 4...N { A[n-1]*exp(A[n]*X) }"},
  235.     {"g!aussian", do_stfunc, "set function gaussian", "",
  236.     "Gaussian series: n = 3, 6...N { A[n-2]*exp(A[n-1]*(X-A[n])^2) }"},
  237.     {"l!egendre", do_stfunc, "set function legendre", "",
  238.         "legendre series: n = 1,...N { Pn(X) }"},
  239.     {"p!olynomial", do_stfunc, "set function polynomial", "",
  240.         "power series: n = 1,...N { A[n]*X^(n-1) }"},
  241.     {"u!ser", do_stfunc, "set function user", "definition",
  242.         "user defined function"},
  243.     {"si!ne", do_stfunc, "set function sine", "",
  244.         "sine series: n = 1,...N { A[n]*sin(n*X) }"},
  245.     {"st!raight", do_stfunc, "set function straight_line", "",
  246.         "straight line: { A[1]+A[2]*X }"},
  247.     { 0,     0,        0,        0,        0 }
  248.     };
  249.  
  250. static int do_stmeth(int argc, char **argv, char *l, Command *cmp);
  251.  
  252. static Command Meths[] = {
  253.     {"?", do_list, "set method ?", "",
  254.         "display this summary"},
  255.     {"la!_reg", do_stmeth, "set method la_reg", "",
  256.         "least absolute deviation linear regression"},
  257.     {"ls_f!it", do_stmeth, "set method ls_fit", "",
  258.         "least square linear fit"},
  259.     {"ls_r!eg", do_stmeth, "set method ls_reg", "",
  260.         "least square linear regression"},
  261.     {"m!l_fit", do_stmeth, "set method ml_fit", "",
  262.         "Marquardt-Levenberg iterative nonlinear fit"},
  263.     {"s!vd_fit", do_stmeth, "set method svd_fit", "",
  264.         "singular value decomposition linear fit"},
  265.     { 0,     0,        0,        0,        0 }
  266.     };
  267.  
  268. static int do_stcomm(int argc, char **argv, char *l, Command *cmp);
  269. static int do_stdata(int argc, char **argv, char *l, Command *cmp);
  270. static int do_stdebug(int argc, char **argv, char *l, Command *cmp);
  271. static int do_stslow(int argc, char **argv, char *l, Command *cmp);
  272. static int do_stsamp(int argc, char **argv, char *l, Command *cmp);
  273. static int do_stplotting(int argc, char **argv, char *l, Command *cmp);
  274. static int do_stparam(int argc, char **argv, char *l, Command *cmp);
  275. static int go_stfunc(int argc, char **argv, char *l, Command *cmp);
  276. static int go_stmeth(int argc, char **argv, char *l, Command *cmp);
  277. static int do_stform(int argc, char **argv, char *l, Command *cmp);
  278. static int do_stiter(int argc, char **argv, char *l, Command *cmp);
  279. static int do_stpager(int argc, char **argv, char *l, Command *cmp);
  280. static int do_stexp(int argc, char **argv, char *l, Command *cmp);
  281. static int do_stnexp(int argc, char **argv, char *l, Command *cmp);
  282. static int do_stpromptcm(int argc, char **argv, char *l, Command *cmp);
  283. static int do_stpromptfm(int argc, char **argv, char *l, Command *cmp);
  284. static int do_stpromptpm(int argc, char **argv, char *l, Command *cmp);
  285. static int do_stvform(int argc, char **argv, char *l, Command *cmp);
  286. static int do_stoutput(int argc, char **argv, char *l, Command *cmp);
  287. static int do_stinput(int argc, char **argv, char *l, Command *cmp);
  288. static int do_sterr(int argc, char **argv, char *l, Command *cmp);
  289.  
  290. static Command Sets[] = {
  291.     {"?", do_list, "set ?", "",
  292.         "display this summary"},
  293.     {"c!omment", do_stcomm, "set comment", "character",
  294.         "change comment escape character (default: '#')"},
  295.     {"da!ta", do_stdata, "set data", "integer",
  296.         "set current vector size"},
  297.     {"de!bug", do_stdebug, "set debug", "integer_list",
  298.         "select and toggle debugging levels"},
  299.     {"er!ror", do_sterr, "set error", "value",
  300.         "define type of math error check"},
  301.     {"ex!pand", do_stexp, "set expand", "",
  302.         "allow history expansion"},
  303.     {"fo!rmat", do_stform, "set format", "string",
  304.         "change number display format (default: \"% 10.8e\")"},
  305.     {"fu!nction", go_stfunc, "set function", "string [userdef]",
  306.         "set function to fit"},
  307.     {"in!put", do_stinput, "set input", "filename",
  308.         "select cmode 'read' command input file"},
  309.     {"it!eration", do_stiter, "set iteration", "integer",
  310.         "set iteration number for nonlinear fits (default: 10)"},
  311.     {"m!ethod", go_stmeth, "set method", "string",
  312.         "select fitting method"},
  313.     {"noex!pand", do_stnexp, "set noexpand", "",
  314.         "disable history expansion"},
  315.     {"ou!tput", do_stoutput, "set output", "filename",
  316.         "select cmode 'print' command output file"},
  317.     {"pag!er", do_stpager, "set pager", "pager_name",
  318.         "select pager (default: PAGER environement)"},
  319.     {"par!ameters", do_stparam, "set parameters", "NAME size",
  320.         "define parameter list to be NAME[1] to NAME[size]"},
  321.     {"pl!otting", do_stplotting, "set plotting", "string",
  322.         "select plotting program (default: /usr/local/bin/gnuplot)"},
  323.     {"prompt-cm", do_stpromptcm, "set prompt-cm", "string",
  324.         "select C-calculator mode prompt (default: \"cmode> \")"},
  325.     {"prompt-fm", do_stpromptfm, "set prompt-fm", "string",
  326.         "select fitting mode prompt (default: \"fudgit> \")"},
  327.     {"prompt-pm", do_stpromptpm, "set prompt-pm", "string",
  328.         "select plotting mode prompt (default: \"pmode> \")"},
  329.     {"sa!mples", do_stsamp, "set samples", "integer",
  330.         "change vector maximum capacity (default: 4000)"},
  331.     {"sl!owterm", do_stslow, "set slowterm", "",
  332.         "toggle prompt after system command"},
  333.     {"vf!ormat", do_stvform, "set vformat", "string",
  334.         "change format for number expansion (default: \"%.3g\")"},
  335.     { 0,     0,        0,        0,        0 }
  336.     };
  337.  
  338. static int do_shcomm(int argc, char **argv, char *l, Command *cmp);
  339. static int do_shdata(int argc, char **argv, char *l, Command *cmp);
  340. static int do_shdebug(int argc, char **argv, char *l, Command *cmp);
  341. static int do_shslow(int argc, char **argv, char *l, Command *cmp);
  342. static int do_shsamp(int argc, char **argv, char *l, Command *cmp);
  343. static int do_shplotting(int argc, char **argv, char *l, Command *cmp);
  344. static int do_shfunc(int argc, char **argv, char *l, Command *cmp);
  345. static int do_shmeth(int argc, char **argv, char *l, Command *cmp);
  346. static int do_shform(int argc, char **argv, char *l, Command *cmp);
  347. static int do_shiter(int argc, char **argv, char *l, Command *cmp);
  348. static int do_shpager(int argc, char **argv, char *l, Command *cmp);
  349. static int do_shfit(int argc, char **argv, char *l, Command *cmp);
  350. static int do_shtab(int argc, char **argv, char *l, Command *cmp);
  351. static int do_shmem(int argc, char **argv, char *l, Command *cmp);
  352. static int do_shvform(int argc, char **argv, char *l, Command *cmp);
  353. static int do_svvec(int argc, char **argv, char *mode, Command *cmp);
  354. static int do_shmac(int argc, char **argv, char *l, Command *cmp);
  355. static int do_svpar(int argc, char **argv, char *mode, Command *cmp);
  356. static int do_shsetup(int argc, char **argv, char *l, Command *cmp);
  357. static int do_svvar(int argc, char **argv, char *mode, Command *cmp);
  358. static int do_shexp(int argc, char **argv, char *l, Command *cmp);
  359. static int do_shpromptcm(int argc, char **argv, char *l, Command *cmp);
  360. static int do_shpromptfm(int argc, char **argv, char *l, Command *cmp);
  361. static int do_shpromptpm(int argc, char **argv, char *l, Command *cmp);
  362. static int do_shoutput(int argc, char **argv, char *l, Command *cmp);
  363. static int do_shinput(int argc, char **argv, char *l, Command *cmp);
  364. static int do_sherr(int argc, char **argv, char *l, Command *cmp);
  365.  
  366. static Command Shows[] = {
  367.     {"?", do_list, "show ?", "",
  368.         "display this summary"},
  369.     {"c!omment", do_shcomm, "show comment", "",
  370.         "display current comment escape character"},
  371.     {"da!ta", do_shdata, "show data", "",
  372.         "show current vector size"},
  373.     {"de!bug", do_shdebug, "show debug", "",
  374.         "display current debugging levels"},
  375.     {"er!ror", do_sherr, "show error", "",
  376.         "display type of math error check"},
  377.     {"ex!pansion", do_shexp, "show expansion", "",
  378.         "display current expansion value"},
  379.     {"fi!t", do_shfit, "show fit", "",
  380.         "complete display of last fit results"},
  381.     {"fo!rmat", do_shform, "show format", "",
  382.         "show current number display format"},
  383.     {"fu!nction", do_shfunc, "show function", "",
  384.         "show current function to fit"},
  385.     {"in!put", do_shinput, "show input", "",
  386.         "display cmode 'read' active input file"},
  387.     {"it!eration", do_shiter, "show iteration", "",
  388.         "show active iteration number for nonlinear fits"},
  389.     {"ma!cros", do_shmac, "show macros", "[macro_name]",
  390.         "display definitions of one or all active macros"},
  391.     {"mem!ory", do_shmem, "show memory", "",
  392.         "display complete state of allocated memory"},
  393.     {"met!hod", do_shmeth, "show method", "",
  394.         "display selected fitting method"},
  395.     {"o!utput", do_shoutput, "show output", "",
  396.         "display cmode 'print' active output file"},
  397.     {"pag!er", do_shpager, "show pager", "",
  398.         "display active pager"},
  399.     {"par!ameters", do_svpar, "show parameters", "[variable_list]",
  400.         "show selected parameter list"},
  401.     {"pl!otting", do_shplotting, "show plotting", "",
  402.         "show selected plotting program"},
  403.     {"prompt-cm", do_shpromptcm, "show prompt-cm", "",
  404.         "select C-calculator mode prompt"},
  405.     {"prompt-fm", do_shpromptfm, "show prompt-fm", "",
  406.         "select fitting mode prompt"},
  407.     {"prompt-pm", do_shpromptpm, "show prompt-pm", "",
  408.         "select plotting mode prompt"},
  409.     {"sa!mples", do_shsamp, "show samples", "",
  410.         "show current vector maximum capacity"},
  411.     {"sl!owterminal", do_shslow, "show slowterminal", "",
  412.         "show current state of slow terminal switch"},
  413.     {"se!tup", do_shsetup, "show setup", "",
  414.         "display current setup"},
  415.     {"va!riables", do_svvar, "show variables", "variable_list",
  416.         "display contents of selected variables"},
  417.     {"ve!ctors", do_svvec, "show vector", "vector_list",
  418.         "display contents of selected vectors"},
  419.     {"vf!ormat", do_shvform, "show vformat", "",
  420.         "show current string expansion format of numbers"},
  421.     {"t!able", do_shtab, "show table", "",
  422.         "display state of internal symbol lookup table"},
  423.     { 0,    0,        0,        0,        0}
  424.     };
  425.  
  426. #ifndef AMIGA
  427. static int do_svhist(int argc, char **argv, char *mode, Command *cmp);
  428. #endif
  429. static int do_svvec(int argc, char **argv, char *mode, Command *cmp);
  430. static int do_svvar(int argc, char **argv, char *mode, Command *cmp);
  431. static int do_svmac(int argc, char **argv, char *mode, Command *cmp);
  432. static int do_svpar(int argc, char **argv, char *mode, Command *cmp);
  433.  
  434. static Command Saves[] = {
  435.     {"?", do_list, "save ?", "",
  436.         "display this summary"},
  437. #ifndef AMIGA
  438.     {"h!istory", do_svhist, "save history", "filename",
  439.         "save all of history to a file"},
  440. #endif
  441.     {"m!acros", do_svmac, "save macros", "filename",
  442.         "save all active macro definitions to a file"},
  443.     {"p!arameters", do_svpar, "save parameters", "[variable_list] filename",
  444.         "save all parameters and errors to a file"},
  445.     {"va!riables", do_svvar, "save variables", "variable_list filename",
  446.         "save specified variables to a file"},
  447.     {"ve!ctors", do_svvec, "save vectors", "vector_list filename",
  448.         "save specified vectors to a file"},
  449.     { 0,    0,        0,            0,        0}
  450.     };
  451.  
  452. static Command Appends[] = {
  453.     {"?", do_list, "append ?", "",
  454.         "display this summary"},
  455. #ifndef AMIGA
  456.     {"h!istory", do_svhist, "append history", "filename",
  457.         "append all of history to a file"},
  458. #endif
  459.     {"m!acros", do_svmac, "append macros", "filename",
  460.         "append all active macro definitions to a file"},
  461.     {"p!arameters", do_svpar, "append parameters", "[variable_list] filename",
  462.         "append all parameters and errors to a file"},
  463.     {"va!riables", do_svvar, "append variables", "variable_list filename",
  464.         "append specified variables to a file"},
  465.     {"ve!ctors", do_svvec, "append vectors", "vector_list filename",
  466.         "append specified vectors to a file"},
  467.     { 0,    0,        0,        0,        0}
  468.     };
  469.  
  470. /* HERE WE START */
  471.  
  472. int Ft_exit (int val);
  473. int Ft_almost (register char *str1, register char *str2);
  474.  
  475. extern int Ft_iolevel (void);
  476. extern int Ft_popio (void);
  477. extern int Ft_killplot (void);
  478. extern int Ft_fits (int argc, char **argv, int ndata);
  479. extern int Ft_pushio (char *string, int type, char *name);
  480. extern int Ft_varcpy (char *, char *);
  481. extern int Ft_readvar (char **argp, Symbol **sym, int *loc, int (*irange)[32], double (*range)[32], int *lines, int num, int exec, char *comname);
  482. extern int Ft_dumplot (double **dblv, int ndata);
  483. extern int Ft_processline (char *lp);
  484. extern int Ft_run_smooth (int argc, char **argv, int ndata);
  485. extern int Ft_run_fft (int argc, char **argv, int dir, int ndata);
  486. #ifndef HPUX
  487. extern int killpg (int, int);
  488. #endif
  489. extern int Ft_setparam (char *name, int n);
  490. extern int Ft_symremove (char *name, int verb);
  491. extern int Ft_clearpush_cwd (void);
  492. extern void Ft_initmathyylex (char *str);
  493. extern int Ft_save_macros (int type, char *name, char *mode);
  494. extern int Ft_showmac (int argc, char **argv, int type);
  495. extern int Ft_showsetup (void);
  496. extern int Ft_showfit (void);
  497. extern int Ft_showmem (void);
  498. extern int Ft_showtable (void);
  499. extern int Ft_more_input (int level, char *iprompt);
  500. extern int Ft_macremove (char *name, int type);
  501. extern int Ft_lock (int i, char *name, char *fname);
  502. extern int Ft_switchif (int val);
  503. extern int Ft_pushif (int val);
  504. extern int Ft_popif (void);
  505. extern int Ft_spline (double *x, double *y, double yp1, double ypn, int n);
  506.  
  507. int Ft_command(int argc, char **argv, char *line)
  508. {
  509.     int i;
  510.     Command *cmp = Ft_Cmds;
  511.  
  512.     if (argv[0][0] == '!') {
  513.         line[0] = ' ';  /* erase the bang */
  514.         return(do_system(0, argv, line, 0));
  515.     }   
  516.     for (i=0; Ft_Cmds[i].name; i++, cmp++)
  517.         if (balmost(argv[0], Ft_Cmds[i].name))
  518.             return(Ft_Cmds[i].func(argc, argv, line, cmp));
  519.    
  520.     fprintf(stderr, "%s: Command not found.\n", argv[0]);
  521.     return(ERRR);
  522. }
  523.  
  524. static int do_list(int c, char **v, char *l, Command *com)
  525. {
  526.     int i;
  527.     FILE *fp = stdout;
  528.     char *cp;
  529.  
  530. #ifndef AMIGA
  531.      if (c == 1 && Ft_Interact && *Ft_Pager) {
  532.         if ((fp = popen(Ft_Pager, "w")) == (FILE *)NULL)  {
  533.             fprintf(stderr, "Warning: Could not open pager %s.\n", Ft_Pager);
  534.             fp = stdout;
  535.         }
  536.     }
  537. #endif AMIGA
  538.     for (i=0; com[i].name; i++) {
  539.         if ((cp = strrchr(com[i].fname, ' ')) == NULL)
  540.             cp = com[i].fname;
  541.         fprintf(fp, "%14s: %s;\n", cp, com[i].help);
  542.     }
  543.     if (fp != stdout) {
  544.         fflush(fp);
  545.         pclose(fp);
  546.     }
  547.    
  548.     return(0);
  549. }
  550.  
  551. static int do_end(int c, char **v, char *l, Command *cmp)
  552. {
  553.     fprintf(stderr, "%s: Not in `foreach' or `while' loop.\n", cmp->fname);
  554.     return(ERRR);
  555. }
  556.  
  557. static int do_fmode(int c, char **v, char *l, Command *cmp)
  558. {
  559.     fprintf(stderr,
  560.     "Warning: %s: Program already in fitting mode: Line ignored.\n",
  561.     cmp->fname);
  562.     return(0);
  563. }
  564.  
  565. static int do_killplot(int c, char **v, char *l, Command *cmp)
  566. {
  567.     extern int Ft_killplot(void);
  568.  
  569.     return(Ft_killplot());
  570. }
  571.  
  572. static int do_stop(int c, char **v, char *l, Command *cmp)
  573. {
  574.     fprintf(stderr, "Warning: %s: Not in macro.\n", cmp->fname);
  575.     if (Ft_iolevel())
  576.         Ft_popio();
  577.     return(0);
  578. }
  579.  
  580. static int do_let(int c, char **v, char *l, Command *cmp)
  581. {
  582.     return(let(c, v, l, cmp));
  583. }
  584.  
  585. static int do_read(int c, char **v, char *l, Command *cmp)
  586. {
  587.     return(dataread(c, v, 0, cmp));
  588. }
  589.  
  590. static int do_exec(int c, char **v, char *l, Command *cmp)
  591. {
  592.     return(dataread(c, v, 1, cmp));
  593. }
  594.  
  595. static int do_quit(int c, char **v, char *l, Command *cmp)
  596. {
  597.     return(Ft_exit(0));
  598. }
  599.  
  600. int Ft_exit(int val)
  601. {
  602.     char buffer[512];
  603.  
  604.     signal_off();
  605.     signal(SIGQUIT, SIG_IGN);
  606.     Ft_killplot();
  607.     fclose(Ft_Outprint);
  608.     signal(SIGCHLD, SIG_IGN);
  609. #ifdef AMIGA
  610.     printf("temporary file(s) called t:fudgit%d* may be left...", getpid());
  611. #else
  612.     sprintf(buffer, "exec /bin/rm -f /tmp/fudgit%d*", getpid());
  613. #endif
  614.     system(buffer);
  615.     sprintf(buffer, "%s/%s", Ft_Home, HISTORY);
  616. #ifndef AMIGA
  617.     if (Ft_Interact) hl_write_history(buffer);
  618. #endif
  619.     if (val == 2) {
  620.         fputs("Do you know why I received that signal?\nIf not report that bug!\n\n", stderr);
  621.     }
  622.     if (val > 1) {
  623.         signal(SIGTERM, SIG_IGN);
  624. #ifdef HPUX
  625.         kill( -getpid(), SIGTERM);
  626. #else
  627.         killpg(getpid(), SIGTERM);
  628. #endif
  629.     }
  630.     exit(val);
  631. }
  632.  
  633. /* BALMOST UTILITY */
  634. static int balmost(register char *str1, register char *str2)  /* account for built-in functions */
  635.                            
  636. {
  637.     if (*str1 == '&')
  638.         str1++;
  639.     return(Ft_almost(str1, str2));
  640. }
  641.  
  642. /* ALMOST UTILITY  */
  643. int Ft_almost(register char *str1, register char *str2)
  644. {
  645.     int ok = 0;
  646.     register int i = 0;
  647.    
  648.     while (*str1 != ' ' && *str1 != '\t' && *str1 != '\n' &&
  649.     *str1 != '\0' && i++ < TOKENSIZE) { /* avoid runaway  */
  650.         if (*str1 != *str2) {
  651.             if (*str2 != '!') {
  652.                 return(0);
  653.             }
  654.             else {
  655.                 ok = 1;
  656.                 str2++;;
  657.                 continue;
  658.             }
  659.         }
  660.         str1++;
  661.         str2++;
  662.     }
  663.     return(ok || *str2 == '!' || *str2 == '\0');
  664. }
  665.  
  666. /*  DO_SET FUNCTION  */
  667. static int go_set(int argc, char **argv, char *l, Command *cmp)
  668. {
  669.     if (argc == 2 && argv[1][0] == '?')
  670.         return(do_list(argc, argv, l, Sets));
  671.     return(subcommand(1, argc, argv, l, Sets));
  672. }
  673.  
  674. /*  DO_SHOW FUNCTION  */
  675. static int go_show(int argc, char **argv, char *l, Command *cmp)
  676. {
  677.     if (argc == 2 && *argv[1] == '?')
  678.         return(do_list(argc, argv, l, Shows));
  679.     return(subcommand(1, argc, argv, "s", Shows));
  680. }
  681.  
  682. /*  DO_APPEND FUNCTION  */
  683. static int go_append(int argc, char **argv, char *l, Command *cmp)
  684. {
  685.     if (argc == 2 && *argv[1] == '?')
  686.         return(do_list(argc, argv, l, Appends));
  687.     return(subcommand(1, argc, argv, "a", Appends));
  688. }
  689.  
  690. /*  DO_SAVE FUNCTION  */
  691. static int go_save(int argc, char **argv, char *l, Command *cmp)
  692. {
  693.     if (argc == 2 && *argv[1] == '?')
  694.         return(do_list(argc, argv, l, Saves));
  695.     return(subcommand(1, argc, argv, "w", Saves));
  696. }
  697.  
  698. /*  DO_SET_FUNCTION FUNCTION  */
  699. static int go_stfunc(int argc, char **argv, char *l, Command *cmp)
  700. {
  701.     if (argc == 3 && *argv[2] == '?')
  702.         return(do_list(argc, argv, l, Funcs));
  703.     return(subcommand(2, argc, argv, l, Funcs));
  704. }
  705.  
  706. /*  DO_SET_METHOD FUNCTION  */
  707. static int go_stmeth(int argc, char **argv, char *l, Command *cmp)
  708. {
  709.     if (argc == 3 && *argv[2] == '?')
  710.         return(do_list(argc, argv, l, Meths));
  711.     return(subcommand(2, argc, argv, l, Meths));
  712. }
  713.  
  714. static int subcommand(int lvl, int argc, char **argv, char *l, Command *cmp)
  715. {
  716.     int i;
  717.  
  718.     if (argc <= lvl) {
  719.         fputs("Command incomplete.\n", stderr);
  720.         return(ERRR);
  721.     }
  722.     for (i=0; cmp->name; i++, cmp++)
  723.         if (Ft_almost(argv[lvl], cmp->name))
  724.             return(cmp->func(argc, argv, l, cmp));
  725.    
  726.     fprintf(stderr, "%s: Name not found.\n", argv[lvl]);
  727.     return(ERRR);
  728. }
  729.  
  730. /* VERSION */
  731. static int do_version(int argc, char **argv, char *l, Command *cmp)
  732. {
  733.     if (argc != 1)
  734.         return(usage(cmp));
  735.     return(Ft_printversion());
  736. }
  737.  
  738. /* COMMENT */
  739. static int do_stcomm(int argc, char **argv, char *l, Command *cmp)
  740. {
  741.     if (argc != 3)
  742.         return(usage(cmp));
  743.     if (argv[2][1] != '\0') {
  744.         fprintf(stderr, "%s: Not a character.\n", argv[2]);
  745.         return(ERRR);
  746.     }
  747.     Ft_Comchar = argv[2][0];
  748.     return(0);
  749. }
  750.  
  751. static int do_shcomm(int argc, char **argv, char *l, Command *cmp)
  752. {
  753.     if (argc != 2)
  754.         return(usage(cmp));
  755.     fprintf(stderr, "%c\n", Ft_Comchar);
  756.     return(0);
  757. }
  758.  
  759. /* DEBUG */
  760. static int do_stdebug(int argc, char **argv, char *l, Command *cmp)
  761. {
  762.     if (argc == 2 || argv[2][0] == '?') {
  763.         fputs("Debugging levels:\n", stderr);
  764.         fputs("\t 0: Clear debugging bits.\n", stderr);
  765.         fputs("\t 1: Echo expanded input lines.\n", stderr);
  766.         fputs("\t 2: Echo raw input lines.\n", stderr);
  767.         fputs("\t 3: Display ignored line numbers while reading data.\n",
  768.         stderr);
  769.         fputs("\t 4: Echo input lines passed to math parser.\n", stderr);
  770.         fputs("\t 5: Debug parser (if compiled with -DYYDEBUG).\n", stderr);
  771.         fputs("\t 6: Trace `if' constructions.\n", stderr);
  772.     }
  773.     else {  /* must be larger than 2 */
  774.         float fldeb;
  775.         int deb;
  776.         int i;
  777. #ifdef YYDEBUG
  778.         extern int Ft_mathyydebug;
  779. #endif
  780.  
  781.         for (i=2;i<argc;i++) {
  782.             if (sscanf(argv[i], "%f", &fldeb) != 1) {
  783.                 fprintf(stderr, "%s: Could not read number \"%s\".\n",
  784.                 cmp->fname, argv[i]);
  785.                 return(ERRR);
  786.             }
  787.             deb = (int)fldeb;
  788.             if (deb)
  789.                 Ft_Debug |= 01<<(deb-1);
  790.             else
  791.                 Ft_Debug = 0;
  792.         }
  793. #ifdef YYDEBUG
  794.         Ft_mathyydebug = (Ft_Debug & DEBUG_PARSER);
  795. #endif
  796.     }
  797.     return(0);
  798. }
  799.  
  800. static int do_shdebug(int argc, char **argv, char *l, Command *cmp)
  801. {
  802.     if (argc != 2)
  803.         return(usage(cmp));
  804.     fprintf(stderr, "%o\n", Ft_Debug);
  805.     return(0);
  806. }
  807.  
  808. /* VFORMAT */
  809. static int do_stvform(int argc, char **argv, char *l, Command *cmp)
  810. {
  811.     if (argc != 3)
  812.         return(usage(cmp));
  813.     sprintf(Ft_Vformat, "%s", argv[2]);
  814.     return(0);
  815. }
  816.  
  817. /* FORMAT */
  818. static int do_stform(int argc, char **argv, char *l, Command *cmp)
  819. {
  820.     if (argc != 3)
  821.         return(usage(cmp));
  822.     sprintf(Ft_Format, "%s", argv[2]);
  823.     sprintf(Ft_TFormat, "\t%s", argv[2]);
  824.     return(0);
  825. }
  826.  
  827. static int do_shvform(int argc, char **argv, char *l, Command *cmp)
  828. {
  829.     if (argc != 2)
  830.         return(usage(cmp));
  831.     fprintf(stderr, "\"%s\"\n", Ft_Vformat);
  832.     return(0);
  833. }
  834.  
  835. static int do_shform(int argc, char **argv, char *l, Command *cmp)
  836. {
  837.     if (argc != 2)
  838.         return(usage(cmp));
  839.     fprintf(stderr, "\"%s\"\n", Ft_Format);
  840.     return(0);
  841. }
  842.  
  843. /* FUNCTION */
  844. static int do_stfunc(int argc, char **argv, char *l, Command *cmp)
  845. {
  846.     int i;
  847.     char *cp;
  848.  
  849.     if (argc != 3)
  850.         return(usage(cmp));
  851.     for (i=0;i<FUNCNUM;i++) {  /* look twice I know!... */
  852.         if (Ft_almost(argv[2], Ft_Function[i].cname)) {
  853.             Ft_Funci = i;
  854.             break;
  855.         }
  856.     }
  857.     if (Ft_Funci != USER)
  858.         return(0);
  859.     /* DO USER */
  860.     if ((cp = Ft_readmacro("user? ")) == NULL) {
  861.         return(ERRR);
  862.     }
  863.     sprintf(Ft_UFunction, "%s", cp);
  864.     return(0);
  865. }
  866.  
  867. static int do_shfunc(int argc, char **argv, char *l, Command *cmp)
  868. {
  869.     if (argc != 2)
  870.         return(usage(cmp));
  871.     if (Ft_Funci == USER)
  872.         fprintf(stdout, "user:\n{\n%s}\n", Ft_UFunction);
  873.     else
  874.         fprintf(stderr, "%s\n", Ft_Function[Ft_Funci].name);
  875.  
  876.     return(0);
  877. }
  878.  
  879. /* ITER */
  880. static int do_stiter(int argc, char **argv, char *l, Command *cmp)
  881. {
  882.     int i;
  883.  
  884.     if (argc != 3)
  885.         return(usage(cmp));
  886.     if (sscanf(argv[2], "%d", &i) != 1) {
  887.         fprintf(stderr, "%s: Could not read value %s.\n",
  888.         cmp->fname, argv[2]);
  889.         return(ERRR);
  890.     }
  891.     Ft_Iter = i;
  892.     return(0);
  893. }
  894.  
  895. static int do_shiter(int argc, char **argv, char *l, Command *cmp)
  896. {
  897.     if (argc != 2)
  898.         return(usage(cmp));
  899.     fprintf(stderr, "%d\n", Ft_Iter);
  900.     return(0);
  901. }
  902.  
  903. /* OUTPUT */
  904. static int do_stoutput(int argc, char **argv, char *l, Command *cmp)
  905. {
  906.     extern FILE *Ft_Outprint;
  907.     extern char Ft_Outname[];
  908.  
  909.     if (argc != 3)
  910.         return(usage(cmp));
  911.     if (Ft_Outprint != stderr && Ft_Outprint != stdout) {
  912.         fflush(Ft_Outprint);
  913.         fclose(Ft_Outprint);
  914.     }
  915.     if (Ft_almost(argv[2], "stdout")) {
  916.         sprintf(Ft_Outname, "stdout");
  917.         Ft_Outprint = stdout;
  918.         return(0);
  919.     }
  920.     if (Ft_almost(argv[2], "stderr")) {
  921.         sprintf(Ft_Outname, "stderr");
  922.         Ft_Outprint = stderr;
  923.         return(0);
  924.     }
  925.     if ((Ft_Outprint = fopen(argv[2], "w")) == (FILE *)NULL) {
  926.         fprintf(stderr, "%s: %s: Permission denied.\n", cmp->fname, argv[2]);
  927.         sprintf(Ft_Outname, "stdout");
  928.         Ft_Outprint = stdout;
  929.         return(ERRR);
  930.     }
  931.     sprintf(Ft_Outname, "%s", argv[2]);
  932.     return(0);
  933. }
  934.  
  935. /* INPUT */
  936. static int do_stinput(int argc, char **argv, char *l, Command *cmp)
  937. {
  938.     if (argc != 3)
  939.         return(usage(cmp));
  940.     if (Ft_Inread != stdin) {
  941.         fclose(Ft_Inread);
  942.     }
  943.     if (Ft_almost(argv[2], "stdin")) {
  944.         sprintf(Ft_Inname, "stdin");
  945.         Ft_Inread = stdin;
  946.         return(0);
  947.     }
  948.     if ((Ft_Inread = fopen(argv[2], "r")) == (FILE *)NULL) {
  949.         fprintf(stderr, "%s: %s: Permission denied.\n", cmp->fname, argv[2]);
  950.         sprintf(Ft_Inname, "stdin");
  951.         Ft_Inread = stdin;
  952.         return(ERRR);
  953.     }
  954.     sprintf(Ft_Inname, "%s", argv[2]);
  955.     return(0);
  956. }
  957.  
  958. static int do_shoutput(int argc, char **argv, char *l, Command *cmp)
  959. {
  960.     if (argc != 2)
  961.         return(usage(cmp));
  962.     fprintf(stderr, "%s\n", Ft_Outname);
  963.     return(0);
  964. }
  965.  
  966. static int do_shinput(int argc, char **argv, char *l, Command *cmp)
  967. {
  968.     if (argc != 2)
  969.         return(usage(cmp));
  970.     fprintf(stderr, "%s\n", Ft_Inname);
  971.     return(0);
  972. }
  973.  
  974. /* PAGER */
  975. static int do_stpager(int argc, char **argv, char *l, Command *cmp)
  976. {
  977.     if (argc != 3)
  978.         return(usage(cmp));
  979.     sprintf(Ft_Pager, "%s", argv[2]);
  980.     return(0);
  981. }
  982.  
  983. static int do_shpager(int argc, char **argv, char *l, Command *cmp)
  984. {
  985.     if (argc != 2)
  986.         return(usage(cmp));
  987.     fprintf(stderr, "%s\n", Ft_Pager);
  988.     return(0);
  989. }
  990.  
  991. /* PLOTTING */
  992. static int do_stplotting(int argc, char **argv, char *l, Command *cmp)
  993. {
  994.     int i;
  995.  
  996.     if (argc < 3)
  997.         return(usage(cmp));
  998.     for (i=0;i<argc-2 && i < MAXPARG-1;i++) {
  999.         sprintf(Ft_Plotting[i], "%s", argv[i+2]);
  1000.     }
  1001.     Ft_Plotting[i][0] = '\0';
  1002.     Ft_killplot();
  1003.     return(0);
  1004. }
  1005.  
  1006. static int do_shplotting(int argc, char **argv, char *l, Command *cmp)
  1007. {
  1008.     int i;
  1009.  
  1010.     if (argc != 2)
  1011.         return(usage(cmp));
  1012.     for (i=0;Ft_Plotting[i][0] != '\0' && i < MAXPARG-1;i++) {
  1013.         fprintf(stderr, "%s ", Ft_Plotting[i]);
  1014.     }
  1015.     fputc('\n', stderr);
  1016.     return(0);
  1017. }
  1018.  
  1019. /* DATA */
  1020. static int do_stdata(int argc, char **argv, char *l, Command *cmp)
  1021. {
  1022.     extern double *Ft_Data;
  1023.     int i;
  1024.  
  1025.     if (argc != 3)
  1026.         return(usage(cmp));
  1027.     if (sscanf(argv[2], "%d", &i) != 1) {
  1028.         fprintf(stderr, "%s: Could not read value %s.\n",
  1029.         cmp->fname, argv[2]);
  1030.         return(ERRR);
  1031.     }
  1032.     if (i<1 || i > Ft_Samples) {
  1033.         fprintf(stderr, "%s: Value out of current capacity.\n",
  1034.         cmp->fname);
  1035.         fputs("Enlarge with `set samples' first.\n", stderr);
  1036.         return(ERRR);
  1037.     }
  1038.     else if (i < (int) *Ft_Data) {
  1039.         fprintf(stderr, "Warning: possible hidden data (%d -> %d).\n",
  1040.         (int) *Ft_Data, i);
  1041.     }
  1042.     *Ft_Data = (double)i;
  1043.     return(0);
  1044. }
  1045.  
  1046. static int do_shdata(int argc, char **argv, char *l, Command *cmp)
  1047. {
  1048.     if (argc != 2)
  1049.         return(usage(cmp));
  1050.     fprintf(stderr, "%d\n", (int) *Ft_Data);
  1051.     return(0);
  1052. }
  1053.  
  1054. /* METHOD */
  1055. static int do_stmeth(int argc, char **argv, char *l, Command *cmp)
  1056. {
  1057.     int i;
  1058.  
  1059.     if (argc != 3)
  1060.         return(usage(cmp));
  1061.     for (i=0;i< METHNUM;i++) {  /* twice again...*/
  1062.         if (Ft_almost(argv[2], Ft_Method[i].cname)) {
  1063.             Ft_Methi = i;
  1064.             return(0);
  1065.         }
  1066.     }
  1067.     fprintf(stderr, "%s: Invalid option.\n.", argv[2]);
  1068.     return(ERRR);
  1069. }
  1070.  
  1071. static int do_shmeth(int argc, char **argv, char *l, Command *cmp)
  1072. {
  1073.     if (argc != 2)
  1074.         return(usage(cmp));
  1075.     fprintf(stderr, "%s\n", Ft_Method[Ft_Methi].name);
  1076.     return(0);
  1077. }
  1078.  
  1079. /* PARAMETERS */
  1080. static int do_stparam(int argc, char **argv, char *l, Command *cmp)
  1081. {
  1082.     float flnumber;
  1083.  
  1084.     if (argc != 4)
  1085.         return(usage(cmp));
  1086.     if (sscanf(argv[3], "%f", &flnumber) != 1) {
  1087.         fprintf(stderr, "%s: Could not read number \"%s\".\n",
  1088.         cmp->fname, argv[3]);
  1089.         return(ERRR);
  1090.     }
  1091.     if (Ft_setparam(argv[2], (int)flnumber) == ERRR) {
  1092.         fprintf(stderr,
  1093.         "%s: Could not set parameter \"%s\".\n", cmp->fname, argv[2]);
  1094.         return(ERRR);
  1095.     }
  1096.     return(0);
  1097. }
  1098.  
  1099. /* SAMPLES */
  1100. static int do_stsamp(int argc, char **argv, char *l, Command *cmp)
  1101. {
  1102.     float flvalue;
  1103.     int value;
  1104.  
  1105.     if (argc != 3)
  1106.         return(usage(cmp));
  1107.     if (sscanf(argv[2], "%f", &flvalue) != 1) {
  1108.         fprintf(stderr, "%s: Could not read number \"%s\".\n",
  1109.         cmp->fname, argv[2]);
  1110.         return(ERRR);
  1111.     }
  1112.     value = (int)flvalue;
  1113.     if (value < 1) {
  1114.         fprintf(stderr, "%s: %d: Illegal value.\n", cmp->fname, value);
  1115.         return(ERRR);
  1116.     }
  1117.     Ft_symremove("@all", 0);
  1118.     Ft_Samples = value;
  1119.     return(0);
  1120. }
  1121.  
  1122. static int do_shsamp(int argc, char **argv, char *l, Command *cmp)
  1123. {
  1124.     if (argc != 2)
  1125.         return(usage(cmp));
  1126.     fprintf(stderr, "%d\n", Ft_Samples);
  1127.     return(0);
  1128. }
  1129.  
  1130. /* SLOWTERM */
  1131. static int do_stslow(int argc, char **argv, char *l, Command *cmp)
  1132. {
  1133.     if (argc != 2)
  1134.         return(usage(cmp));
  1135.     Slowterm = !Slowterm;
  1136.     return(0);
  1137. }
  1138.  
  1139. /* SLOWTERM */
  1140. static int do_shslow(int argc, char **argv, char *l, Command *cmp)
  1141. {
  1142.     if (argc != 2)
  1143.         return(usage(cmp));
  1144.     fprintf(stderr, "%s\n", Slowterm? "on": "off");
  1145.     return(0);
  1146. }
  1147.  
  1148. /* DO_CD FUNCTION */
  1149. static int do_cd(int argc, char **argv, char *l, Command *cmp)
  1150. {
  1151.     extern char Ft_Cwd[PATH_MAXIM];
  1152. #ifndef HPUX   /*  HPUX  use getcwd() for HPUX -- it has no getwd()  */
  1153.     extern char *getwd(char *);
  1154. #endif  /*  HPUX  */
  1155.  
  1156.     switch (argc) {
  1157.         case 1:
  1158.             if (chdir(Ft_Home) == ERRR) {
  1159.                 fprintf(stderr, "%s: ", Ft_Home);
  1160.                 perror("");
  1161.                 return(ERRR);
  1162.             }
  1163.             break;
  1164.         case 2:
  1165.             if (chdir(argv[1]) == ERRR) {
  1166.                 fprintf(stderr, "chdir: %s: ", argv[1]);
  1167.                 perror("");
  1168.                 return(ERRR);
  1169.             }
  1170.             break;
  1171.         default:
  1172.             return(usage(cmp));
  1173.     }
  1174.  
  1175. #ifdef HPUX   /* HPUX  uses getcwd()  */
  1176.     if (getcwd(Ft_Cwd, PATH_MAXIM-1) == (char *) NULL) {
  1177.         perror("getcwd");
  1178. #else
  1179.     if (getwd(Ft_Cwd) == (char *)NULL) {
  1180.         /* getwd places an error message in Cwd */
  1181.         fprintf(stderr, "%s\n", Ft_Cwd);
  1182. #endif  /* HPUX  */
  1183.         return(ERRR);
  1184.     }
  1185.     else if (Ft_Interact) {
  1186.     /* NeXT sometimes echoes it */
  1187. #ifndef NEVER
  1188.         fprintf(stderr, "%s\n", Ft_Cwd);
  1189. #endif
  1190.     }
  1191.     Ft_clearpush_cwd();
  1192.     return(0);
  1193. }
  1194.  
  1195. /* DO_FREE FUNCTION */
  1196. static int do_free(int argc, char **argv, char *line, Command *cmp)
  1197. {
  1198.     int i;
  1199.  
  1200.     if (argc == 1)
  1201.         return(usage(cmp));
  1202.     for (i=1;i<argc;i++) {
  1203.         Ft_symremove(argv[i], 1);
  1204.     }
  1205.     return(0);
  1206. }
  1207.  
  1208. /* DO_PAUSE FUNCTION  */
  1209. static int do_pause(int argc, char **argv, char *line, Command *cmp)
  1210. {
  1211.     int value;
  1212.     float flvalue;
  1213.  
  1214.     if (argc < 2)
  1215.         return(usage(cmp));
  1216.  
  1217.     if (argc > 2) {
  1218.         char *cp;
  1219.  
  1220.         cp = line + strlen(argv[0]) + strlen(argv[1]) + 2;
  1221.         line[strlen(line)-1] = '\0';
  1222.         fprintf(stderr, "%s ", cp);
  1223.         fflush(stderr);
  1224.     }
  1225.     if (sscanf(argv[1], "%f", &flvalue) != 1) {
  1226.         fprintf(stderr, "%s: Could not read number \"%s\".\n",
  1227.         cmp->fname, argv[1]);
  1228.         return(ERRR);
  1229.     }
  1230.     if ((value = (int)flvalue) >= 0) {
  1231.         sleep(value);
  1232.         fputc('\n', stderr);
  1233.         fflush(stderr);
  1234.     }
  1235.     else {
  1236.         char fromline[LINESIZE];
  1237.  
  1238.         fgets(fromline, LINESIZE, stdin);
  1239.     }
  1240.     return(0);
  1241. }
  1242.  
  1243. /* DO_PWD FUNCTION  */
  1244. static int do_pwd(int argc, char **argv, char *l, Command *cmp)
  1245. {
  1246.     extern char Ft_Cwd[PATH_MAXIM];
  1247.  
  1248.     if (argc != 1)
  1249.         return(usage(cmp));
  1250.  
  1251.     fprintf(stderr, "%s\n", Ft_Cwd);
  1252.     return(0);
  1253. }
  1254.  
  1255. /* DO_LS FUNCTION */
  1256. static int do_ls(int argc, char **argv, char *line, Command *cmp)
  1257. {
  1258.     char fromline[LINESIZE +16];
  1259.     int  val;
  1260.  
  1261.     signal_off();
  1262.     if (argc == 1) {
  1263.         val = system("exec ls -FC");
  1264.     }
  1265.     else {
  1266.         char *cp;
  1267.  
  1268.         cp = line + strlen(argv[0]) + 1;
  1269.         sprintf(fromline, "exec ls -FC %s", cp);
  1270.         val = system(fromline);
  1271.     }
  1272.     signal_on();
  1273.     if (Slowterm && Ft_Interact && !Ft_iolevel()) {
  1274.         fputs("\nHit return to continue", stdout);
  1275.         fgets(fromline, LINESIZE, stdin);
  1276.     }
  1277.     return(val);
  1278. }
  1279.  
  1280. /* LET FUNCTION */
  1281. static int let(int argc, char **argv, char *line, Command *cmp)
  1282. {
  1283.     char *argp;
  1284.     void Ft_let(char *string);
  1285.  
  1286.     if (argc == 1)
  1287.         return(usage(cmp));
  1288.     if (argc == 0) {
  1289.         argp = line;
  1290.     }
  1291.     else {
  1292.         argp = line + strlen(argv[0]) + 1;
  1293.     }
  1294.     Ft_let(argp);
  1295.     return(0);
  1296. }
  1297.  
  1298. void Ft_let(char *string)
  1299. {
  1300.     Ft_initcode();
  1301.     Ft_initmathyylex(string);
  1302.     Ft_mathyyparse();
  1303. }
  1304.  
  1305. /* DO_SAVE FUNCTIONS */
  1306. #ifndef AMIGA
  1307. static int do_svhist(int argc, char **argv, char *mode, Command *cmp)
  1308. {
  1309.     if (argc != 3)
  1310.         return(usage(cmp));
  1311.     if (*mode == 'w')
  1312.         return(hl_write_history(argv[2]) ? ERRR: 0);
  1313.     return(hl_append_history(512, argv[2]) ? ERRR: 0);
  1314. }
  1315.  
  1316. static int do_hist(int argc, char **argv, char *mode, Command *cmp)
  1317. {
  1318.     HIST_ENTRY **h_list;
  1319.     FILE *fp = stderr;
  1320.     int i;
  1321.  
  1322.     if (argc > 2)
  1323.         return(usage(cmp));
  1324.     if ((h_list = hl_history_list())) {
  1325.         if (Ft_Interact && *Ft_Pager) {
  1326.            if ((fp = popen(Ft_Pager, "w")) == (FILE *)NULL)  {
  1327.                 fprintf(stderr, "Warning: %s: Could not open pager %s.\n",
  1328.                 cmp->fname, Ft_Pager);
  1329.                 fp = stderr;
  1330.             }
  1331.         }
  1332.         for (i=0; h_list[i]; i++) {
  1333.             fprintf(fp, "%d: %s\n", (i + hl_history_base), h_list[i]->line);
  1334.         }
  1335.     }
  1336.     if (fp != stderr) {
  1337.         fflush(fp);
  1338.         pclose(fp);
  1339.     }
  1340.  
  1341.     return(0);
  1342. }
  1343. #endif
  1344.  
  1345. /* MACROS  */
  1346. static int do_svmac(int argc, char **argv, char *mode, Command *cmp)
  1347. {
  1348.     if (argc != 3)
  1349.         return(usage(cmp));
  1350.     return(Ft_save_macros(AMACRO, argv[2], mode));
  1351. }
  1352.  
  1353. /* SHOW FUNCTIONS */
  1354. static int do_shmac(int argc, char **argv, char *l, Command *cmp)
  1355. {
  1356.     if (argc > 3)
  1357.         return(usage(cmp));
  1358.     return(Ft_showmac(argc, argv, AMACRO));
  1359. }
  1360.  
  1361. /* SETUP */
  1362. static int do_shsetup(int argc, char **argv, char *l, Command *cmp)
  1363. {
  1364.     if (argc == 1)
  1365.         return(usage(cmp));
  1366.     return(Ft_showsetup());
  1367. }
  1368.  
  1369. /* FIT  */
  1370. static int do_shfit(int argc, char **argv, char *l, Command *cmp)
  1371. {
  1372.     if (argc == 1)
  1373.         return(usage(cmp));
  1374.     return(Ft_showfit());
  1375. }
  1376.  
  1377. /* MEMORY */
  1378. static int do_shmem(int argc, char **argv, char *l, Command *cmp)
  1379. {
  1380.     if (argc != 2)
  1381.         return(usage(cmp));
  1382. #if !defined(NOMALLINFO)
  1383.     return(Ft_showmem());
  1384. #else
  1385.     fprintf(stderr, "%s: Function not supported.\n", cmp->fname);
  1386.     return(ERRR);
  1387. #endif
  1388. }
  1389.  
  1390. /* TABLE */
  1391. static int do_shtab(int argc, char **argv, char *l, Command *cmp)
  1392. {
  1393.     if (argc != 2)
  1394.         return(usage(cmp));
  1395.     return(Ft_showtable());
  1396. }
  1397.  
  1398. /* DO_ECHO FUNCTION */
  1399. static int do_echo(int argc, char **argv, char *line, Command *cmp)
  1400. {
  1401.     if (argc == 1) {
  1402.         fputc('\n', stdout);
  1403.     }
  1404.     else {
  1405.         char *cp;
  1406.  
  1407.         cp = line + strlen(argv[0]) + 1;
  1408.         fputs(cp, stdout);
  1409.     }
  1410.     return(0);
  1411. }
  1412.  
  1413. /* DO_SYSTEM FUNCTION */
  1414. static int do_system(int argc, char **argv, char *line, Command *cmp)
  1415. {
  1416.     int val;
  1417.     char fromline[80];
  1418.     extern char Ft_Shell[];
  1419.     extern int errno;
  1420.  
  1421.     errno = 0;
  1422.     signal_off();
  1423.     switch (argc) {
  1424.         case 0:
  1425.             val = system(line);
  1426.             break;
  1427.         case 1:
  1428.             sprintf(fromline, "exec %s", Ft_Shell);
  1429.             val = system(fromline);
  1430.             fputc('\n', stderr);
  1431.             break;
  1432.         default:
  1433.             val = system((line + strlen(argv[0]) + 1));
  1434.             break;
  1435.     }
  1436.     signal_on();
  1437.     if (Slowterm && Ft_Interact && !Ft_iolevel()) {
  1438.         fputs("\nHit return to continue", stdout);
  1439.         fgets(fromline, 80, stdin);
  1440.     }
  1441.     if (val) {
  1442.         if (val == ERRR)
  1443.             perror("system");
  1444.         else
  1445.             fputs("Warning: System returned an error.\n", stderr);
  1446.         return(ERRR);
  1447.     }
  1448.     return(0);
  1449. }
  1450.  
  1451. /* DO_VI FUNCTION */
  1452. static int do_vi(int c, char **v, char *line, Command *cmp)
  1453. {
  1454.     signal_off();
  1455.     system(line);
  1456.     signal_on();
  1457.     return(0);
  1458. }
  1459.  
  1460. /* DO_FIT FUNCTION  */
  1461. static int do_fit(int argc, char **argv, char *l, Command *cmp)
  1462. {
  1463.     if (argc != 4 && (argc != 3 || (Ft_Methi != LS_REG && Ft_Methi != LA_REG)))
  1464.         return(usage(cmp));
  1465.     return(Ft_fits(argc, argv, (int) *Ft_Data));
  1466. }
  1467.  
  1468. /* DO_ADJUST FUNCTION */
  1469. static int do_adjust(int argc, char **argv, char *l, Command *cmp)
  1470. {
  1471.     int i, j;
  1472.     float flj;
  1473.  
  1474.     if (argc < 2 || (int) *Ft_Param < argc - 1) {
  1475.         fprintf(stderr, "%s: Invalid number of parameters.\n",
  1476.         cmp->fname);
  1477.         return(ERRR);
  1478.     }
  1479.     else if (Ft_Methi != ML_FIT && Ft_Methi != LS_FIT) {
  1480.         fprintf(stderr, "%s: Warning: Not active under `%s' method.\n",
  1481.         cmp->fname, Ft_Method[Ft_Methi].name);
  1482.     }
  1483.     for (i=1;i < argc; i++) {
  1484.         if (sscanf(argv[i], "%f", &flj) != 1) {
  1485.             fprintf(stderr, "%s: Could not read number \"%s\".\n",
  1486.             cmp->fname, argv[i]);
  1487.             return(ERRR);
  1488.         }
  1489.         j = (int)flj;
  1490.         if (j<1 || j> (int) *Ft_Param) {
  1491.             fprintf(stderr, "%s: Invalid parameter %d.\n",
  1492.             cmp->fname, j);
  1493.             Ft_Mlist = 0;
  1494.             return(ERRR);
  1495.         }
  1496.         Ft_Miparx1[i] = j;
  1497.     }
  1498.     Ft_Mlist = i -1;
  1499.     return(0);
  1500. }
  1501.  
  1502. /* DO_LOAD FUNCTION */
  1503. static int do_load(int argc, char **argv, char *l, Command *cmp)
  1504. {
  1505.     if (argc != 2)
  1506.         return(usage(cmp));
  1507.     return(Ft_pushio(argv[1], AFILE, (char *) 0));
  1508. }
  1509.  
  1510. /* DO_READ FUNCTION  */
  1511. static int dataread(int argc, char **argv, int exec, Command *cmp)
  1512. {
  1513.     int i;
  1514.     char *sc;
  1515.     char name[TOKENSIZE];
  1516.     Symbol *table[MAXVAR];
  1517.     int loctable[MAXVAR];
  1518.     int irange[2][MAXVAR];
  1519.     int lines[2];
  1520.     double range[2][MAXVAR];
  1521.     extern Symbol *Ft_lookup(char *);
  1522.     extern double strtod(const char *, char **);
  1523.  
  1524.     if (argc < 3)
  1525.         return(usage(cmp));
  1526.     if (argc > MAXVAR) {
  1527.         fprintf(stderr, "%s: %d: Too many variables.\n",
  1528.         cmp->fname, argc-2);
  1529.         return(ERRR);
  1530.     }
  1531.     lines[0] = 0;
  1532. #ifndef INT_MAX
  1533. #define INT_MAX 2147483647
  1534. #endif
  1535.     lines[1] = INT_MAX;
  1536.     for (i=0; i<argc-2;i++) {
  1537.         if (sscanf(argv[i+2], "%[^:]:%d", name, &loctable[i]) != 2) {
  1538.             fprintf(stderr, "%s: Bad argument \"%s\".\n",
  1539.             cmp->fname, argv[i+2]);
  1540.             return(ERRR);
  1541.         }
  1542.         if ((table[i] = Ft_lookup(name)) == 0) {
  1543.             if (Ft_varcpy(0, name) != VEC) {
  1544.                 fprintf(stderr, "%s: %s: Illegal vector name.\n",
  1545.                 cmp->fname, name);
  1546.                 return(ERRR);
  1547.             }
  1548.             table[i] = Ft_install(name, UNDEFVEC, Ft_Samples);
  1549.         }
  1550.         else if (table[i]->type != VEC && table[i]->type != UNDEFVEC) {
  1551.             fprintf(stderr, "%s: %s: Not a vector.\n",
  1552.             cmp->fname, table[i]->name);
  1553.             return(ERRR);
  1554.         }
  1555.         if ((sc = strstr(argv[i+2], "{")) != 0) {
  1556.             char *eh;
  1557.             char low[TOKENSIZE+1];
  1558.             char high[TOKENSIZE+1];
  1559.  
  1560.             if (strstr(argv[i+2], "}") == 0) {
  1561.                 fprintf(stderr, "%s: %s: Unmatched brace.\n",
  1562.                 cmp->fname, argv[i+2]);
  1563.                 return(ERRR);
  1564.             }
  1565.             if (sscanf(sc, "{%[^:]:%[^}]", low, high) != 2) {
  1566.                 fprintf(stderr, "%s: Line range misconstruction at: %s.\n",
  1567.                 cmp->fname, sc);
  1568.                 return(usage(cmp));
  1569.             }
  1570.             if (strcmp(low, "*") == 0) {
  1571.                 lines[0] = 0;
  1572.             }
  1573.             else {
  1574.                 lines[0] = (int) strtod(low, &eh);
  1575. #ifndef SUN3
  1576.                 if (*eh != '\0') {
  1577. #else
  1578.                 if (*--eh != '\0') {  /* SUN OS3.5 strtod brain dead */
  1579. #endif
  1580.                     fprintf(stderr,
  1581.                     "%s: Low line range misconstruction at: %s.\n",
  1582.                     cmp->fname, sc);
  1583.                     return(usage(cmp));
  1584.                 }
  1585.             }
  1586.             if (strcmp(high, "*") == 0) {
  1587.                 lines[1] = Ft_Samples + 32;
  1588.             }
  1589.             else {
  1590.                 lines[1] = (int) strtod(high, &eh);
  1591. #ifndef SUN3
  1592.                 if (*eh != '\0') {
  1593. #else
  1594.                 if (*--eh != '\0') {  /* SUN OS3.5 strtod brain dead */
  1595. #endif
  1596.                     fprintf(stderr,
  1597.                     "%s: High range line misconstruction at: %s.\n",
  1598.                     cmp->fname, sc);
  1599.                     return(usage(cmp));
  1600.                 }
  1601.             }
  1602.         }
  1603.         if ((sc = strstr(argv[i+2], "[")) != 0) {
  1604.             char *eh;
  1605.             char low[TOKENSIZE+1];
  1606.             char high[TOKENSIZE+1];
  1607.  
  1608.             if (strstr(argv[i+2], "]") == 0) {
  1609.                 fprintf(stderr, "%s: %s: Unmatched bracket.\n",
  1610.                 cmp->fname, argv[i+2]);
  1611.                 return(ERRR);
  1612.             }
  1613.             if (sscanf(sc, "[%[^:]:%[^]]", low, high) != 2) {
  1614.                 fprintf(stderr, "%s: Range misconstruction at: %s.\n",
  1615.                 cmp->fname, sc);
  1616.                 return(usage(cmp));
  1617.             }
  1618.             if (strcmp(low, "*") == 0) {
  1619.                 irange[0][i] = 0;
  1620.             }
  1621.             else {
  1622.                 irange[0][i] = 1;
  1623.                 range[0][i] = strtod(low, &eh);
  1624. #ifndef SUN3
  1625.                 if (*eh != '\0') {
  1626. #else
  1627.                 if (*--eh != '\0') {  /* SUN OS3.5 strtod brain dead */
  1628. #endif
  1629.                     fprintf(stderr, "%s: Low range misconstruction at: %s.\n",
  1630.                     cmp->fname, sc);
  1631.                     return(usage(cmp));
  1632.                 }
  1633.             }
  1634.             if (strcmp(high, "*") == 0) {
  1635.                 irange[1][i] = 0;
  1636.             }
  1637.             else {
  1638.                 irange[1][i] = 1;
  1639.                 range[1][i] = strtod(high, &eh);
  1640. #ifndef SUN
  1641.                 if (*eh != '\0') {
  1642. #else
  1643.                 if (*--eh != '\0') {  /* SUN OS3.5 strtod brain dead */
  1644. #endif
  1645.                     fprintf(stderr, "%s: High range misconstruction at: %s.\n",
  1646.                     cmp->fname, sc);
  1647.                     return(usage(cmp));
  1648.                 }
  1649.             }
  1650.         }
  1651.         else {
  1652.             irange[0][i] = irange[1][i] = 0;
  1653.         }
  1654.     }
  1655.     return(Ft_readvar(argv, table, loctable, irange, range, lines, argc-2, exec,
  1656.     cmp->fname));
  1657. }
  1658.  
  1659. static int do_svvec(int argc, char **argv, char *mode, Command *cmp)
  1660. {
  1661.     FILE *fp = stdout;
  1662.     int i, j;
  1663.     Symbol *table[MAXVAR];
  1664.     extern Symbol *Ft_lookup(char *);
  1665.  
  1666.     if ((int) *Ft_Data == 0) {
  1667.         fprintf(stderr, "%s: No data!\n", cmp->fname);
  1668.         return(ERRR);
  1669.     }
  1670.     if (argc > MAXVAR) {
  1671.         fprintf(stderr, "%s: %d: Too many vectors.\n", cmp->fname, argc);
  1672.         return(ERRR);
  1673.     }
  1674.     if (*mode != 's') argc--;
  1675.     if (argc < 3)
  1676.         return(usage(cmp));
  1677.     for (i=0;i<argc-2;i++) {
  1678.         if ((table[i] = Ft_lookup(argv[i+2])) == 0) {
  1679.             fprintf(stderr, "%s: %s: Unknown vector.\n",
  1680.             cmp->fname, argv[i+2]);
  1681.             return(ERRR);
  1682.         }
  1683.         if (table[i]->type != VEC) {
  1684.             fprintf(stderr, "%s: %s: Not a vector.\n",
  1685.             cmp->fname, table[i]->name);
  1686.             return(ERRR);
  1687.         }
  1688.     }
  1689.     switch (*mode) {
  1690.         case 'w':
  1691.         case 'a':
  1692.             if ((fp = fopen(argv[argc], mode)) == 0) {
  1693.                 fprintf(stderr, "%s: %s: Permission denied.\n",
  1694.                 cmp->fname, argv[argc]);
  1695.                 return(ERRR);
  1696.             }
  1697.             /********
  1698.             fputc(Ft_Comchar, fp);
  1699.             for (j=0;j<argc-2;j++) {
  1700.                 fprintf(fp, "\t%s", table[j]->name);
  1701.             }
  1702.             fputc('\n', fp);
  1703.             ********/
  1704.             for (i=1;i<= (int) *Ft_Data;i++) {
  1705.                 fprintf(fp, Ft_Format, table[0]->u.vec[i]);
  1706.                 for (j=1;j<argc-2;j++) {
  1707.                     fprintf(fp, Ft_TFormat, table[j]->u.vec[i]);
  1708.                 }
  1709.                 fputc('\n', fp);
  1710.             }
  1711.             fclose(fp);
  1712.             break;
  1713.         case 's':
  1714.             if ((int) *Ft_Data > 24 && Ft_Interact && *Ft_Pager) {
  1715.                 if ((fp = popen(Ft_Pager, "w")) == (FILE *)NULL)  {
  1716.                     fprintf(stderr, "Warning: %s: Could not open pager %s.\n",
  1717.                     cmp->fname, Ft_Pager);
  1718.                     fp = stdout;
  1719.                 }
  1720.             }
  1721.             for (i=1;i<=(int) *Ft_Data;i++) {
  1722.                 if (fprintf(fp, " %4d:", i) < 0)
  1723.                     break;
  1724.                 for (j=0;j<argc-2;j++) {
  1725.                     fprintf(fp, Ft_TFormat, table[j]->u.vec[i]);
  1726.                 }
  1727.                 if (fputc('\n', fp) < 0)
  1728.                     break;
  1729.             }
  1730.             if (fp != stdout) {
  1731.                 fflush(fp);
  1732.                 pclose(fp);
  1733.             }
  1734.             break;
  1735.         default:
  1736.             fprintf(stderr, "%s: Impossible printing mode.\n",
  1737.             cmp->fname);
  1738.             Ft_catcher(ERRR);
  1739.     }
  1740.     return(0);
  1741. }
  1742.  
  1743. /*
  1744. typedef union {
  1745.     double db;
  1746.     char* str;
  1747.     } Vardesc;
  1748. */
  1749.  
  1750. static int do_svvar(int argc, char **argv, char *mode, Command *cmp)
  1751. {
  1752.     FILE *fp = stdout;
  1753.     int j;
  1754.     Vardesc vvec[MAXVAR];
  1755.     int astring[MAXVAR];
  1756.  
  1757.     if (*mode != 's')
  1758.         argc--;
  1759.     if (argc < 3)
  1760.         return(usage(cmp));
  1761.     if (argc-2 > MAXVAR) {
  1762.         fprintf(stderr, "%s: %d: Too many variables.\n",
  1763.         cmp->fname, argc-2);
  1764.         return(ERRR);
  1765.     }
  1766.     if (splitvar(2, argc, argv, vvec, astring, cmp) == ERRR)
  1767.         return(ERRR);
  1768.  
  1769.     switch(*mode) {
  1770.         case 'w':
  1771.         case 'a':
  1772.             if ((fp = fopen(argv[argc], mode)) == 0) {
  1773.                 fprintf(stderr, "%s: %s: Permission denied.\n",
  1774.                 cmp->fname, argv[argc]);
  1775.                 return(ERRR);
  1776.             }
  1777.             if (astring[0]) {
  1778.                    fputs(vvec[0].str, fp);
  1779.             }
  1780.             else {
  1781.                    fprintf(fp, Ft_Format, vvec[0].db);
  1782.             }
  1783.             for (j=1;j<argc-2;j++) {
  1784.                 if (astring[j]) {
  1785.                     fprintf(fp, "\t%s", vvec[j].str);
  1786.                 }
  1787.                 else {
  1788.                     fprintf(fp, Ft_TFormat, vvec[j].db);
  1789.                 }
  1790.             }
  1791.             fputc('\n', fp);
  1792.             fclose(fp);
  1793.             break;
  1794.         case 's':
  1795.             for (j=0;j<argc-2;j++) {
  1796.                 if (astring[j]) {
  1797.                     fprintf(fp, "\t%s", vvec[j].str);
  1798.                 }
  1799.                 else {
  1800.                     fprintf(fp, Ft_TFormat, vvec[j].db);
  1801.                 }
  1802.             }
  1803.             fputc('\n', fp);
  1804.             break;
  1805.         default:
  1806.             fprintf(stderr, "%s: Impossible printing mode.\n", cmp->fname);
  1807.             Ft_catcher(ERRR);
  1808.     }
  1809.     return(0);
  1810. }
  1811.  
  1812. static int splitvar(int ifrom, int xto, char **argv, Vardesc *dbvec, int *astringvec, Command *cmp)
  1813. {
  1814.     register int i, j;
  1815.     char *cp;
  1816.     int index;
  1817.     Symbol *sym;
  1818.     char name[TOKENSIZE+4];
  1819.     extern Symbol *Ft_lookup(char *);
  1820.  
  1821.     for (i=0, j=ifrom; j<xto; i++, j++) {
  1822.         sscanf(argv[j], "%[^[]", name);
  1823.         index = 0;
  1824.         if ((sym = Ft_lookup(name)) == 0) {
  1825.             fprintf(stderr, "%s: %s: Unknown variable.\n", cmp->fname, name);
  1826.             return(ERRR);
  1827.         }
  1828.         astringvec[i] = 0;  /* assume they all are numbers */
  1829.         switch(sym->type) {
  1830.             case BLTINSTRVAR:
  1831.             case BLTINSTRCONST:
  1832.             case STRVAR:
  1833.             case STRCONST:
  1834.                 astringvec[i] = 1;
  1835.                 dbvec[i].str = sym->u.str;
  1836.                 break;
  1837.             case BLTINVAR:
  1838.             case BLTINCONST:
  1839.             case VAR:
  1840.             case CONST:
  1841.                 dbvec[i].db = sym->u.val;
  1842.                 break;
  1843.             case PARAM:
  1844.                 if ((int) *Ft_Param == 0) {
  1845.                     fprintf(stderr, "%s: %s: Null size vector!\n",
  1846.                     cmp->fname, name);
  1847.                     return(ERRR);
  1848.                 }
  1849.                 if ((cp = strstr(argv[j], "[")) != NULL) {
  1850.                     if (sscanf(cp+1, "%d]", &index) != 1) {
  1851.                         fprintf(stderr,
  1852.                         "%s: %s: Badly formed vector element.\n",
  1853.                         cmp->fname, argv[j]);
  1854.                         return(ERRR);
  1855.                     }
  1856.                 }
  1857.                 if (index < 1 || (int) *Ft_Param < index) {
  1858.                     fprintf(stderr, "%s: %s: Illegal parameter index.\n",
  1859.                     cmp->fname, name);
  1860.                     return(ERRR);
  1861.                 }
  1862.                 dbvec[i].db = sym->u.vec[index];
  1863.                 break;
  1864.             case VEC:
  1865.                 if ((int) *Ft_Data == 0) {
  1866.                     fprintf(stderr, "%s: %s: Null size vector!\n",
  1867.                     cmp->fname, name);
  1868.                     return(ERRR);
  1869.                 }
  1870.                 if ((cp = strstr(argv[j], "[")) != NULL) {
  1871.                     if (sscanf(cp+1, "%d]", &index) != 1) {
  1872.                         fprintf(stderr,
  1873.                         "%s: %s: Badly formed vector element.\n",
  1874.                         cmp->fname, argv[j]);
  1875.                         return(ERRR);
  1876.                     }
  1877.                 }
  1878.                 if (index < 1 || (int) *Ft_Data < index) {
  1879.                     fprintf(stderr, "%s: %s: Illegal vector index.\n",
  1880.                     cmp->fname, name);
  1881.                     return(ERRR);
  1882.                 }
  1883.                 dbvec[i].db = sym->u.vec[index];
  1884.                 break;
  1885.             default:
  1886.                 fprintf(stderr, "%s: %s: Not a printable variable.\n",
  1887.                 cmp->fname, sym->name);
  1888.                 return(ERRR);
  1889.         }
  1890.     }
  1891.     return(i);
  1892. }
  1893.  
  1894. static int do_svpar(int argc, char **argv, char *mode, Command *cmp)
  1895. {
  1896.     int j;
  1897.     FILE *fp = stdout;
  1898.     Vardesc vvec[MAXVAR];
  1899.     int astring[MAXVAR];
  1900.     extern char Ft_Pname[];
  1901.  
  1902.     if ((int) *Ft_Param == 0) {
  1903.         fprintf(stderr, "%s: No parameters!\n", cmp->fname);
  1904.         return(ERRR);
  1905.     }
  1906.     if (*mode != 's')
  1907.         argc--;
  1908.     if (argc < 2)
  1909.         return(usage(cmp));
  1910.     if (argc-2 > MAXVAR) {
  1911.         fprintf(stderr, "%s: %d: Too many variables.\n",
  1912.         cmp->fname, argc-2);
  1913.         return(ERRR);
  1914.     }
  1915.     if (argc > 2) {
  1916.         if (splitvar(2, argc, argv, vvec, astring, cmp) == ERRR)
  1917.             return(ERRR);
  1918.     }
  1919.     switch (*mode) {
  1920.         case 'w':
  1921.         case 'a':
  1922.         if ((fp = fopen(argv[argc], mode)) == 0) {
  1923.             fprintf(stderr, "%s: %s: Permission denied.\n",
  1924.             cmp->fname, argv[argc]);
  1925.             return(ERRR);
  1926.         }
  1927.         if (argc > 2) {
  1928.             if (astring[0]) {
  1929.                 fputs(vvec[0].str, fp);
  1930.             }
  1931.             else {
  1932.                 fprintf(fp, Ft_Format, vvec[0].db);
  1933.             }
  1934.             for (j=1;j<argc-2;j++) {
  1935.                 if (astring[j]) {
  1936.                        fprintf(fp, "\t%s", vvec[j].str);
  1937.                 }
  1938.                 else {
  1939.                        fprintf(fp, Ft_TFormat, vvec[j].db);
  1940.                 }
  1941.             }
  1942.             fputc('\t', fp);
  1943.         }
  1944.         fprintf(fp, Ft_Format, Ft_A[1]);
  1945.         fprintf(fp, Ft_TFormat, Ft_DA[1]);
  1946.         for (j=2;j<=(int) *Ft_Param;j++) {
  1947.             fprintf(fp, Ft_TFormat, Ft_A[j]);
  1948.             fprintf(fp, Ft_TFormat, Ft_DA[j]);
  1949.         }
  1950.         fputc('\n', fp);
  1951.         fclose(fp);
  1952.         break;
  1953.         case 's':
  1954.         if ((int) *Ft_Param > 24 && Ft_Interact && *Ft_Pager) {
  1955.             if ((fp = popen(Ft_Pager, "w")) == (FILE *)NULL)  {
  1956.                 fprintf(stderr, "Warning: %s: Could not open pager %s.\n",
  1957.                 cmp->fname, Ft_Pager);
  1958.                 fp = stdout;
  1959.             }
  1960.         }
  1961.         if (argc > 2) {
  1962.             if (astring[0]) {
  1963.                 fputs(vvec[0].str, fp);
  1964.             }
  1965.             else {
  1966.                 fprintf(fp, Ft_Format, vvec[0].db);
  1967.             }
  1968.             for (j=1;j<argc-2;j++) {
  1969.                 if (astring[j]) {
  1970.                        fprintf(fp, "\t%s", vvec[j].str);
  1971.                 }
  1972.                 else {
  1973.                        fprintf(fp, Ft_TFormat, vvec[j].db);
  1974.                 }
  1975.             }
  1976.             fputc('\n', fp);
  1977.         }
  1978.         for (j=1;j <= (int) *Ft_Param;j++) {
  1979.             fprintf(fp, " %s[%d]:", Ft_Pname, j);
  1980.             fprintf(fp, Ft_TFormat, Ft_A[j]);
  1981.             fprintf(fp, " +/- ");
  1982.             fprintf(fp, Ft_TFormat, Ft_DA[j]);
  1983.             fputc('\n', fp);
  1984.         }
  1985.         if (fp != stdout) {
  1986.             fflush(fp);
  1987.             pclose(fp);
  1988.         }
  1989.         break;
  1990.         default:
  1991.         fprintf(stderr, "%s: Impossible printing mode.\n", cmp->fname);
  1992.         Ft_catcher(ERRR);
  1993.     }
  1994.     return(0);
  1995. }
  1996.  
  1997. #include <setjmp.h>
  1998. /* CMODE FUNCTION */
  1999. static int do_cmode(int argc, char **argv, char *l, Command *cmp)
  2000. {
  2001.     extern jmp_buf Ft_Jump;
  2002.     extern FILE *Ft_Outprint;
  2003.     int val;
  2004.  
  2005.     if (argc != 1)  /* send to let if some command  */
  2006.         return(let(argc, argv, l, cmp));
  2007.     if (Ft_Interact && !Ft_iolevel()) {
  2008.         fputs("\tUse `fmode' or ^D to come back...\n", stderr);
  2009.         setjmp(Ft_Jump);
  2010.     }
  2011.     Ft_Mode = CMODE;
  2012.     for(Ft_initcode(); (val = Ft_more_input(0, 0));Ft_initcode()) {
  2013.         if (val == ERRR)
  2014.             continue;
  2015.         Ft_mathyyparse();
  2016.     }
  2017.     fflush(Ft_Outprint);
  2018.     return(0);
  2019. }   
  2020.  
  2021. /* DO_DUMPLOT FUNCTION  */
  2022. static int do_dumplot(int argc, char **argv, char *l, Command *cmp)
  2023. {
  2024.     int i;
  2025.     Symbol *sym;
  2026.     double *dblv[MAXDARG];
  2027.     extern Symbol *Ft_lookup(char *);
  2028.  
  2029.     if ((int) *Ft_Data == 0) {
  2030.         fprintf(stderr, "%s: No data!\n", cmp->fname);
  2031.         return(ERRR);
  2032.     }
  2033.  
  2034.     if (argc < 2 || MAXDARG < argc) {
  2035.         fprintf(stderr, "%s: %d: Unsupported number of argument.\n",
  2036.         cmp->fname, argc);
  2037.         return(ERRR);
  2038.     }
  2039.     for (i=0;i<argc-1;i++) {
  2040.         if ((sym = Ft_lookup(argv[i+1])) == 0) {
  2041.             fprintf(stderr, "%s: %s: Unknown vector.\n",
  2042.             cmp->fname, argv[i+1]);
  2043.             return(ERRR);
  2044.         }
  2045.         if (sym->type != VEC) {
  2046.             fprintf(stderr, "%s: %s: Not a vector.\n",
  2047.             cmp->fname, sym->name);
  2048.             return(ERRR);
  2049.         }
  2050.         dblv[i] = sym->u.vec;
  2051.     }
  2052.     dblv[i] = 0;
  2053.     return(Ft_dumplot(dblv, (int) *Ft_Data));
  2054. }
  2055.  
  2056. /* DO_DEFINE FUNCTION */
  2057. static int do_defmac(int argc, char **argv, char *l, Command *cmp)
  2058. {
  2059.     Macro *mac;
  2060.     char *cp;
  2061.  
  2062.     if (argc != 3)
  2063.         return(usage(cmp));
  2064.  
  2065.     if (Ft_almost(argv[1], "m!acro") || Ft_almost(argv[1], "u!nmacro")) {
  2066.         fprintf(stderr, "%s: %s: Too dangerous to define that!\n",
  2067.         cmp->fname, argv[1]);
  2068.         return(ERRR);
  2069.     }
  2070.     if ((mac = Ft_maclook(argv[1], ANALIAS)) != NULL) {
  2071.         fprintf(stderr, "%s: %s: Name conflict with existing alias.\n",
  2072.         cmp->fname, argv[1]);
  2073.         return(ERRR);
  2074.     }
  2075.     if ((cp = Ft_readmacro("macro? ")) == NULL) {
  2076.         return(ERRR);
  2077.     }
  2078.     if ((mac = Ft_maclook(argv[1], AMACRO)) != NULL) {
  2079.         if (Ft_macremove(argv[1], AMACRO) == ERRR) {
  2080.             return(ERRR);
  2081.         }
  2082.     }
  2083.     if ((mac = Ft_macinstall(argv[1], cp, AMACRO)) == NULL) {
  2084.         return(ERRR);
  2085.     }
  2086.     mac->nargs = atoi(argv[2]);
  2087.     return(0);
  2088. }
  2089.  
  2090. /* DO_UNDEFINE FUNCTION */
  2091. static int do_udefmac(int argc, char **argv, char *l, Command *cmp)
  2092. {
  2093.     int i;
  2094.  
  2095.     if (argc < 2)
  2096.         return(usage(cmp));
  2097.     for (i=1;i<argc;i++) {
  2098.         Ft_macremove(argv[i], AMACRO);
  2099.     }
  2100.     return(0);
  2101. }
  2102.  
  2103. /* DO_WHILE FUNCTION */
  2104. static int do_while(int argc, char **argv, char *line, Command *cmp)
  2105. {
  2106.     char condition[TOKENSIZE+16];
  2107.     extern double *Ft_If_value;
  2108.     Macro *lmac;
  2109.     int liolevel;
  2110.     int ivalue;
  2111.     char *cp;
  2112.     char macroname[MAXMACRO];
  2113.     extern int Ft_Dolevel;
  2114.     extern char *Ft_read_loop(char **argv, char *fprom);
  2115.  
  2116.     if (argc < 2 || argv[1][0] != '(')
  2117.         return(usage(cmp));
  2118.     
  2119.     sprintf(condition, "if_value = %s\n", argv[1]);
  2120.     if (let(0, argv, condition, 0) == ERRR)
  2121.         return(ERRR);
  2122.     sprintf(macroname, "while_loop%d", Ft_Dolevel+1);
  2123.     if ((lmac = Ft_maclook(macroname, AMACRO)) != NULL) {
  2124.            if (Ft_macremove(macroname, AMACRO) == ERRR) {
  2125.                return(ERRR);
  2126.            }
  2127.     }
  2128.     if (argc > 2) {
  2129.         cp = line + strlen(argv[0]) + strlen(argv[1]) + 2;
  2130.     }
  2131.     else if ((cp = Ft_read_loop(argv, "while")) == NULL) {
  2132.            return(ERRR);
  2133.     }
  2134.     if ((lmac = Ft_macinstall(macroname, cp, AMACRO)) == NULL) {
  2135.         return(ERRR);
  2136.     }
  2137.     lmac->nargs = 0;
  2138.     liolevel = Ft_iolevel();
  2139.     Ft_Dolevel++;
  2140.     ivalue = (int) *Ft_If_value;
  2141.     while (ivalue) {
  2142.         if (macrun(lmac, liolevel) == ERRR) {
  2143.             Ft_Dolevel--;
  2144.             return(ERRR);
  2145.         }
  2146.         if (let(0, argv, condition, 0) == ERRR) {
  2147.             Ft_Dolevel--;
  2148.             return(ERRR);
  2149.         }
  2150.         ivalue = (int) *Ft_If_value;
  2151.     }
  2152.     Ft_Dolevel--;
  2153.     return(0);
  2154. }
  2155.  
  2156. /* DO_FOREACH FUNCTION */
  2157. static int do_foreach(int argc, char **argv, char *line, Command *cmp)
  2158. {
  2159.     Macro *lmac;
  2160.     Symbol *lvar;
  2161.     FILE *pfp;
  2162.     int liolevel;
  2163.     int looploop, i, c;
  2164.     char *cp;
  2165.     char macroname[MAXMACRO];
  2166.     char commandline[LINESIZE+4];
  2167.     extern int Ft_Dolevel;
  2168.     extern char *Ft_read_loop(char **argv, char *fprom);
  2169.  
  2170.     if (argc < 4)
  2171.         return(usage(cmp));
  2172.     if (!Ft_almost(argv[2], "in"))
  2173.         return(usage(cmp));
  2174.     if (Ft_varcpy(0, argv[1]) != STRVAR) {
  2175.         fprintf(stderr, "foreach: %s: Not a legal string name.\n", argv[1]);
  2176.         return(ERRR);
  2177.     }
  2178.     if ((lvar = Ft_lookup(argv[1])) != NULL) {
  2179.         if (Ft_symremove(argv[1], 1)) {
  2180.             return(ERRR);
  2181.         }
  2182.     }
  2183.     lvar = Ft_install(argv[1], STRVAR, TOKENSIZE+4);
  2184.     cp = line + strlen(argv[0]) + strlen(argv[1]) + strlen(argv[2]) + 3;
  2185.     sprintf(commandline, "%s", cp);
  2186.     sprintf(macroname, "foreach_loop%d", Ft_Dolevel+1);
  2187.     if ((lmac = Ft_maclook(macroname, AMACRO)) != NULL) {
  2188.         if (Ft_macremove(macroname, AMACRO) == ERRR) {
  2189.             return(ERRR);
  2190.         }
  2191.     }
  2192.     if ((cp = Ft_read_loop(argv, "foreach")) == NULL) {
  2193.         return(ERRR);
  2194.     }
  2195.     if ((lmac = Ft_macinstall(macroname, cp, AMACRO)) == NULL) {
  2196.         return(ERRR);
  2197.     }
  2198.     lmac->nargs = 0;
  2199.  
  2200.     if ((pfp = popen(commandline, "r")) == (FILE *)NULL) {
  2201.         commandline[strlen(commandline)-1] = '\0';
  2202.         fprintf(stderr, "%s: Could not open `%s' process.\n",
  2203.         cmp->fname, commandline);
  2204.         return(ERRR);
  2205.     }
  2206.     liolevel = Ft_iolevel();
  2207.     Ft_Dolevel++;
  2208.     looploop = 0;
  2209.     cp = lvar->u.str;
  2210.     while (1) {
  2211.         i = 0;
  2212.         while ((c = fgetc(pfp)) >= 0 && isspace(c) ) { /* swallow space */
  2213.             ;
  2214.         }
  2215.         if (c < 0 ) {        /* EOF ? */
  2216.             break;
  2217.         }
  2218.         cp[i++] = c;
  2219.         /* read the token */
  2220.         while ((c = fgetc(pfp)) >= 0 && !isspace(c) && i < LINESIZE) {
  2221.             cp[i++] = c;
  2222.         }
  2223.         if (i >= LINESIZE) {
  2224.             fprintf(stderr, "Warning: %s: String %d is too long.\n",
  2225.             cmp->fname, ++looploop);
  2226.             continue;
  2227.         }
  2228.         cp[i] = 0;
  2229.         if (i == 0)
  2230.             break;
  2231.         if (macrun(lmac, liolevel) == ERRR) {
  2232.             fflush(pfp);
  2233.             pclose(pfp);
  2234.             Ft_Dolevel--;
  2235.             return(ERRR);
  2236.         }
  2237.         looploop++;
  2238.     }
  2239.     fflush(pfp);
  2240.     pclose(pfp);
  2241.     Ft_Dolevel--;
  2242.     if (looploop == 0) {
  2243.         commandline[strlen(commandline)-1] = '\0';
  2244.         fprintf(stderr, "Warning: %s: Command `%s' is an empty loop.\n",
  2245.         cmp->fname, commandline);
  2246.     }
  2247.     return(0);
  2248. }
  2249.  
  2250. static int macrun(Macro *mac, int level)
  2251. {
  2252.     char *cp;
  2253.     int eof;
  2254.     extern char *Ft_nextline(char *, int *);
  2255.  
  2256.     Ft_pushio(mac->line, AMACRO, mac->name);
  2257.     while (Ft_iolevel() > level) {
  2258.         if ((cp = Ft_nextline(Ft_Prompt_fm, &eof)) == NULL) {
  2259.             continue;
  2260.         }
  2261.         if (Ft_processline(cp) == ERRR) {
  2262.             return(ERRR);
  2263.         }
  2264.     }
  2265.     return(0);
  2266. }
  2267.  
  2268. static int do_alias(int argc, char **argv, char *line, Command *cmp)
  2269. {
  2270.     Macro *mac;
  2271.     char *cp;
  2272.  
  2273.     switch (argc) {
  2274.     case 1:
  2275.         return(Ft_showmac(2, argv, ANALIAS));
  2276.     case 2:   
  2277.         if ((mac = Ft_maclook(argv[1], ANALIAS)) != NULL) {
  2278.             fputs(mac->line, stdout);
  2279.         }
  2280.         return(0);
  2281.     default:   
  2282.         if (Ft_almost(argv[1], "al!ias") || Ft_almost(argv[1], "una!lias")) {
  2283.             fprintf(stderr, "%s: %s: Too dangerous to alias that!\n",
  2284.             argv[1], cmp->fname);
  2285.             return(ERRR);
  2286.         }
  2287.         if (*argv[1] == '&') {
  2288.             fprintf(stderr,
  2289.             "%s: %s: Not allowed to start an alias with `&'!\n",
  2290.             argv[1], cmp->fname);
  2291.             return(ERRR);
  2292.         }
  2293.         if (Ft_almost(argv[2], argv[1])) {
  2294.             fprintf(stderr, "%s: %s: Circular alias.\n",
  2295.             cmp->fname, argv[1]);
  2296.             return(ERRR);
  2297.         }
  2298.         if ((mac = Ft_maclook(argv[1], AMACRO)) != NULL) {
  2299.             fprintf(stderr, "%s: %s: Name conflict with existing macro.\n",
  2300.             cmp->fname, argv[1]);
  2301.             return(ERRR);
  2302.         }
  2303.         if ((mac = Ft_maclook(argv[1], ANALIAS)) != NULL) {
  2304.             if (Ft_macremove(argv[1], ANALIAS) == ERRR) {
  2305.                 return(ERRR);
  2306.             }
  2307.         }
  2308.         cp = line + strlen(argv[0]) + strlen(argv[1]) + 2;
  2309.         if ((mac = Ft_macinstall(argv[1], cp, ANALIAS)) == NULL) {
  2310.             return(ERRR);
  2311.         }
  2312.         mac->nargs = 0;
  2313.         return(0);
  2314.     }
  2315. }
  2316.  
  2317. static int do_unalias(int argc, char **argv, char *l, Command *cmp)
  2318. {
  2319.     int i;
  2320.  
  2321.     if (argc < 2)
  2322.         return(usage(cmp));
  2323.     for (i=1;i<argc;i++) {
  2324.         Ft_macremove(argv[i], ANALIAS);
  2325.     }
  2326.     return(0);
  2327. }
  2328.  
  2329. static int do_lock(int argc, char **argv, char *l, Command *cmp)
  2330. {
  2331.     int i, j;
  2332.  
  2333.     if (argc < 2)
  2334.         return(usage(cmp));
  2335.     for (j=0, i=1;i<argc;i++) {
  2336.         j += Ft_lock(1, argv[i], cmp->fname);
  2337.     }
  2338.     if (j)
  2339.         return(ERRR);
  2340.     return(0);
  2341. }
  2342.  
  2343. static int do_unlock(int argc, char **argv, char *l, Command *cmp)
  2344. {
  2345.     int i;
  2346.  
  2347.     if (argc < 2)
  2348.         return(usage(cmp));
  2349.     for (i=1;i<argc;i++) {
  2350.         Ft_lock(0, argv[i], cmp->fname);
  2351.     }
  2352.     return(0);
  2353. }
  2354.  
  2355. static int usage(Command *cmd)
  2356. {
  2357.     fprintf(stderr, "Usage: `%s' %s\n", cmd->fname, cmd->usage);
  2358.     return(ERRR);
  2359. }
  2360.  
  2361. static int do_stexp(int argc, char **argv, char *l, Command *cmp)
  2362. {
  2363.     if (argc != 2)
  2364.         return(usage(cmp));
  2365.     Ft_Expandhist = 1;
  2366.     return(0);
  2367. }
  2368.  
  2369. static int do_stnexp(int argc, char **argv, char *l, Command *cmp)
  2370. {
  2371.     if (argc != 2)
  2372.         return(usage(cmp));
  2373.     Ft_Expandhist = 0;
  2374.     return(0);
  2375. }
  2376.    
  2377. static int do_shexp(int argc, char **argv, char *l, Command *cmp)
  2378. {
  2379.     if (argc != 2)
  2380.         return(usage(cmp));
  2381.     fprintf(stderr, "%s\n", (Ft_Expandhist == 1? "on": "off") );
  2382.     return(0);
  2383. }
  2384.  
  2385. static int do_smooth(int argc, char **argv, char *l, Command *cmp)
  2386. {
  2387.     if (argc != 4)
  2388.         return(usage(cmp));
  2389.     return(Ft_run_smooth(argc, argv, (int) *Ft_Data));
  2390. }
  2391.  
  2392. static int do_fft(int argc, char **argv, char *l, Command *cmp)
  2393. {
  2394.     if (argc != 5)
  2395.         return(usage(cmp));
  2396.     return(Ft_run_fft(argc, argv, 1, (int) *Ft_Data));
  2397. }
  2398.  
  2399. static int do_invfft(int argc, char **argv, char *l, Command *cmp)
  2400. {
  2401.     if (argc != 5)
  2402.         return(usage(cmp));
  2403.     return(Ft_run_fft(argc, argv, -1, (int) *Ft_Data));
  2404. }
  2405.  
  2406. static int do_stpromptfm(int argc, char **argv, char *l, Command *cmp)
  2407. {
  2408.     if (argc != 3)
  2409.         return(usage(cmp));
  2410.     strncpy(Ft_Prompt_fm, argv[2], MAXPROMPT);
  2411.     Ft_Prompt_fm[MAXPROMPT] = '\0';
  2412.     return(0);
  2413. }
  2414.  
  2415. static int do_stpromptcm(int argc, char **argv, char *l, Command *cmp)
  2416. {
  2417.     if (argc != 3)
  2418.         return(usage(cmp));
  2419.     strncpy(Ft_Prompt_cm, argv[2], MAXPROMPT);
  2420.     Ft_Prompt_cm[MAXPROMPT] = '\0';
  2421.     return(0);
  2422. }
  2423.  
  2424. static int do_stpromptpm(int argc, char **argv, char *l, Command *cmp)
  2425. {
  2426.     if (argc != 3)
  2427.         return(usage(cmp));
  2428.     strncpy(Ft_Prompt_pm, argv[2], MAXPROMPT);
  2429.     Ft_Prompt_pm[MAXPROMPT] = '\0';
  2430.     return(0);
  2431. }
  2432.  
  2433. static int do_shpromptpm(int argc, char **argv, char *l, Command *cmp)
  2434. {
  2435.     if (argc != 2)
  2436.         return(usage(cmp));
  2437.     fputs(Ft_Prompt_pm, stderr);
  2438.     return(0);
  2439. }
  2440.  
  2441. static int do_shpromptcm(int argc, char **argv, char *l, Command *cmp)
  2442. {
  2443.     if (argc != 2)
  2444.         return(usage(cmp));
  2445.     fputs(Ft_Prompt_cm, stderr);
  2446.     return(0);
  2447. }
  2448.  
  2449. static int do_shpromptfm(int argc, char **argv, char *l, Command *cmp)
  2450. {
  2451.     if (argc != 2)
  2452.         return(usage(cmp));
  2453.     fputs(Ft_Prompt_fm, stderr);
  2454.     return(0);
  2455. }
  2456.  
  2457. static int do_sterr(int argc, char **argv, char *l, Command *cmp)
  2458. {
  2459.     if (argc == 2 || argv[2][0] == '?') {
  2460.         fputs("Error check levels:\n", stderr);
  2461.         fputs("\t 0: Clear check bits.\n", stderr);
  2462.         fputs("\t 1: Check for `infinity' values.\n", stderr);
  2463.         fputs("\t 2: Check for `not a number' values.\n", stderr);
  2464.         fputs("\t 3: Check for `out of domain' math function errors.\n",
  2465.         stderr);
  2466.         fputs("\t 4: Check for `out of range' math function errors.\n",
  2467.         stderr);
  2468.     }
  2469.     else {
  2470.          int chk, i;
  2471.         float flchk;
  2472.  
  2473.         for (i=2;i<argc;i++) {
  2474.             if (sscanf(argv[i], "%f", &flchk) != 1) {
  2475.                 fprintf(stderr, "%s: Could not read number \"%s\".\n",
  2476.                 cmp->fname, argv[i]);
  2477.                 return(ERRR);
  2478.             }
  2479.             chk = (int)flchk;
  2480.             if (chk)
  2481.                 Ft_Check |= 01<<(chk-1);
  2482.             else
  2483.                 Ft_Check = 0;
  2484.         }
  2485.     }
  2486.     return(0);
  2487. }
  2488.  
  2489. static int do_sherr(int argc, char **argv, char *l, Command *cmp)
  2490. {
  2491.     extern int Ft_Check;
  2492.  
  2493.     if (argc != 2)
  2494.         return(usage(cmp));
  2495.     fprintf(stderr, "%o\n", Ft_Check);
  2496.     return(0);
  2497. }
  2498.  
  2499. static int do_if(int argc, char **argv, char *line, Command *cmp)
  2500. {
  2501.     char condition[TOKENSIZE+16];
  2502.     extern double *Ft_If_value;
  2503.     int elseif;
  2504.     int ivalue;
  2505.  
  2506.     elseif = Ft_almost(cmp->fname, "else");  /* who called me? */
  2507.     if (argc < 3 || argv[1][0] != '(') {
  2508.         if (!elseif) {
  2509.             return(usage(cmp));
  2510.         }
  2511.         else {
  2512.             fputs("if: Bad 'else if' construction.\n", stderr);
  2513.             return(ERRR);
  2514.         }
  2515.     }
  2516.     sprintf(condition, "if_value = %s\n", argv[1]);
  2517.     if (let(0, argv, condition, 0) == ERRR)
  2518.         return(ERRR);
  2519.     ivalue = (int) *Ft_If_value;
  2520.     if (!ivalue) { /* FALSE */
  2521.         if (Ft_almost(argv[2], "th!en")) {
  2522.             if (elseif) {
  2523.                 return(Ft_switchif(FALSE_IF));
  2524.             }
  2525.             else {
  2526.                 return(Ft_pushif(FALSE_IF));
  2527.             }
  2528.         }
  2529.     }
  2530.     if (elseif) {     /* TRUE */
  2531.         if (Ft_switchif(TRUE_IF) == ERRR)
  2532.             return(ERRR);
  2533.         return(0);
  2534.     }
  2535.     if (!Ft_almost(argv[2], "th!en")) {
  2536.         char *cp;
  2537.  
  2538.         cp = line + strlen(argv[0]) + strlen(argv[1]) + 2;
  2539.         return(Ft_command(argc-2, argv+2, cp));
  2540.     }
  2541.     return(Ft_pushif(TRUE_IF));
  2542. }
  2543.  
  2544. static int do_else(int argc, char **argv, char *line, Command *cmp)
  2545. {
  2546.     if (argc == 1)
  2547.         return(Ft_switchif(FORCED_IF));
  2548.     if (Ft_almost(argv[1], "if")) {
  2549.         char *cp;
  2550.  
  2551.         cp = line + strlen(argv[0]) + 1;
  2552.         return(do_if(argc-1, argv+1, cp, cmp));
  2553.     }
  2554.     return(usage(cmp));
  2555. }
  2556.  
  2557. static int do_endif(int argc, char **argv, char *line, Command *cmp)
  2558. {
  2559.     if (argc != 1)
  2560.         return(usage(cmp));
  2561.     return(Ft_popif());
  2562. }
  2563.  
  2564. static int do_parse(int argc, char **argv, char *line, Command *cmp)
  2565. {
  2566.     int i;
  2567.  
  2568.     fprintf(stderr, "line: %s", line);
  2569.     for (i=0; i< argc;i++)
  2570.         fprintf(stderr, "argv[%d]: %s\n", i, argv[i]);
  2571.     return(0);
  2572. }
  2573.  
  2574. static int do_spline(int argc, char **argv, char *line, Command *cmp)
  2575. {
  2576.     double dy1, dyn;
  2577.     double *vec1, *vec2;
  2578.     Symbol *sym;
  2579.     extern Symbol *Ft_lookup(char *);
  2580.  
  2581.     if (3 > argc || argc > 5)
  2582.         return(usage(cmp));
  2583.  
  2584.     dyn = dy1 = 1.0e30; /* natural by default */
  2585.     switch (argc) {
  2586.         case 5:
  2587.         if (strcmp(argv[5], "*") != 0 && sscanf(argv[4], "%lf", &dyn) != 1) {
  2588.             fprintf(stderr,
  2589.             "%s: Could not read number from argument 5.\n", cmp->fname);
  2590.             return(ERRR);
  2591.         }
  2592.         case 4:
  2593.         if (strcmp(argv[4], "*") != 0 && sscanf(argv[3], "%lf", &dy1) != 1) {
  2594.             fprintf(stderr,
  2595.             "%s: Could not read number from argument 4.\n", cmp->fname);
  2596.             return(ERRR);
  2597.         }
  2598.         case 3:
  2599.         break;
  2600.     }
  2601.     if ((sym = Ft_lookup(argv[1])) == NULL || sym->type != VEC) {
  2602.         fprintf(stderr, "%s: %s: No such vector.\n", cmp->fname, argv[1]);
  2603.         return(ERRR);
  2604.     }
  2605.     vec1 = sym->u.vec;
  2606.     if ((sym = Ft_lookup(argv[2])) == NULL || sym->type != VEC) {
  2607.         fprintf(stderr, "%s: %s: No such vector.\n", cmp->fname, argv[2]);
  2608.         return(ERRR);
  2609.     }
  2610.     vec2 = sym->u.vec;
  2611.     return(Ft_spline(vec1, vec2, dy1, dyn, (int) *Ft_Data));
  2612. }
  2613.  
  2614. static void signal_on(void)
  2615. {
  2616.     signal(SIGINT, Ft_catcher);
  2617.     signal(SIGHUP, Ft_catcher);
  2618.     signal(SIGTSTP, Ft_catcher);
  2619. }
  2620.  
  2621. static void signal_off(void)
  2622. {
  2623.     signal(SIGINT, SIG_DFL);
  2624.     signal(SIGHUP, SIG_DFL);
  2625.     signal(SIGTSTP, SIG_DFL);
  2626. }
  2627.  
  2628. /* #if defined(sgi) || defined(sparc) || defined(sun) */
  2629. #ifdef DL_YES
  2630. /* The module for dynamic loading */
  2631. #include "install.c"
  2632. #else  /* AIX or HP-UX */
  2633. #include "install.dummy.c"
  2634. #endif
  2635.